Search code examples
c#asp.net-mvcasp.net-mvc-3entity-framework-4.1ef-database-first

How to use the same table in multiple models?


I'm working with Entity Framework 4.1 in an MVC3 Web Application. I am tasked with re-writing a legacy application with a database w/ approximately 200+ tables, already in place with data, thus taking the Database first approach with EF.

I understand that it's bad practice to create one giant edmx model for the entire app, but after hours of research, I can't get a clear direction on how to move forward because I can't figure out how to re-use common tables in more than one model. But I'd like to break up my models into smaller, managable contexts.

When I place a common table (such as Users) in two models, the project throws a compilation error in the form of:

The type 'Project.Models.EntityX' already contains a definition for 'EntityX_PropertyY'

The closest I've found to a workaround was here: http://connect.microsoft.com/VisualStudio/feedback/details/366721/entity-framework-the-type-xxx-already-contains-a-definition-for-x

Posted by Microsoft on 9/17/2008 at 5:18 PM

This issue is by design. The work-around is to either put the models in a different folder (for C# & ASP.NET projects), or to set the custom tool namespace (for C# & VB projects).

This was back in '08. I couldn't get either option to work, and I'm wondering if there is a better way to go about architecting the project so that I am able to use the same table in more than one model?


Solution

  • Our team went through all these posts for our project (~600 tables). A big caveat to my answer here is that we haven't finished the project yet, so not all learning has taken place. I can only offer what we've learned so far.

    Essentially, what you want to do is not possible in a realistic way (currently, that I know of).

    Our requirements were to be able to use a visual designer (not necessarily the Visual Studio designer), and to not have to hack around in a bunch of auto-generated files (or create tools to hack the files automatically) because that's just a recipe for disaster in so many ways.

    We ended up with two possible solutions, noting that what we really wanted is a logical grouping of the tables:

    • Use the designer in LLBLGen (note: not free for commercial use), which can logically separate the tables into different "views" of the database

    • Separate the tables into business-based subsets (i.e., sales, reporting, etc.), with the overlapping tables repeated using different names, and possibly a different set of columns in each subdomain

    During our testing phase we really liked LLBLGen's designer; however, the code generation options are dizzying (definitely written by a programmer for programmers) and the output left a lot to be desired (on my first attempt, it generated code that didn't compile). If you're willing to put a few $ into your project and spend some time testing things out, I would still recommend that you try it out for yourself (there is a free trial); as I said, the designer is quite nice, and reading around on the internet, there seem to be many success stories.

    Needless to say, we selected the latter solution. This worked for us because in our business model, when we have a "shared" table, in all but one of the subdomain models this table is read-only and we aren't worried about propagating changes between all the subdomain models (i.e., we only need a certain view of the data from each subdomain). This may not be the same case for you. It is extra maintenance overhead if you start making drastic changes to the underlying schema, but since you're working with a legacy database, that probably won't be the case. We decided that tradeoff was worth it to keep the tooling within our existing development environment. (Note: we're using a lightly-modified POCO text template to generate the entity classes themselves. If nothing else, this part was a really good decision.)

    At only ~200 tables, I would say try putting them all into a single model, even just as an experiment. You'll definitely want to use your beefiest development box for this... When we tried this using our model (EF 4.0) we had to kill it mid-process.

    During our readings, we did see some rumblings about supporting the model "views" directly in the Visual Studio designer. If this existed, we would absolutely be using it. As it is, though, I suspect that kind of feature is on the back-burner. 200-table projects are definitely niche compared to projects with 100 tables or less, which don't really need such a feature.