Using multiple edmx file vs. one large edmx file? - entity-framework

I'm new to the Entity model thing and i'm looking for an advise how to organize my Entity model.
should i create one entity model file (.edmx) which will contain all the tables in my database or should i break it logical files for user, orders, products, etc.
Please let me know which one is better and what the pros/cons (if any) of each alternative.
Thanks.

I'm going to go against the grain here. I've built 2 large applications with EF now, one with a single edmx and one with several. There are pros and cons but generally I found life to be much easier with one edmx. The reason is that there is almost never a real separation of domains within an app, even if there appears to be from the start. New requirements pop up asking you to relate entities in different edmx's then you have to refactor and continually move things around.
All arguments for dividing will soon be obsolete when EF 5 introduces Multiple Diagrams, which is the only real benefit for dividing edmx files in the first place. You don't want to have to see everything you're not working on and you don't want a performance impact.
In my app with the divided edmx's we now have some duplicate entities to get the benefit of navigation properties. Maybe your app has a true separation of domains, but usually everything connects to the user. I'm considering merging two of the now but it will be a lot of work. So I would say keep them together until it becomes a problem.

Having one big EDM containing all the entities generally is NOT a good practice and is not recommended. You should come up with different sets of domain models each containing related objects while each set is unrelated and disconnected from the other one.
Take a look at this post where I explained this matter in detail:
Does it make sense to create a single diagram for all entities?

i think we should keep multiple edmx files in our project. it's like 1-edmx file -- one aggregate (collection of related objects). as per ddd (domain drive design) we can have more than one aggregates in our model. we can keep one edmx file for each aggregate

Related

Combine Code First & Database First In Single Model?

Is there a way to combine code-first and database-first in the same context? We are running into massive development-time performance problems when editing the EDMX file (it takes 1.5 minutes to save). I've moved our non-insert/update/delete UDFs/stored procs to some custom T4 templates that automatically generate model-first code, but I can't seem to get OnModelCreating to be called when EDMX is involved.
Other things we've considered, but won't work for one reason or another:
We can't (reasonably) separate our code to multiple contexts as there is a lot of overlap in our entity relationships. It also seems like quite a people who have gone this route regret it.
We tried having 2 different contexts, but there are quite a few joins between Entities & UDFs. This may be our last hope, but I'd REALLY like to avoid it.
We can't switch to Dapper since we have unfortunately made heavy use of IQueryable.
We tried to go completely to Code-First, but there are features that we are using in EDMX that aren't supported (mostly related to insert/update/delete stored procedure mapping).
Take a look at the following link. I answered another question in a similar fashion:
How to use Repository pattern using Database first approach in entity framework
As I mentioned in that post, I would personally try to switch to a Code First approach and get rid of the EDMX files as it is already deprecated and most importantly, the maintenance effort is considerable and much more complex compared with the Code First approach.
It is not that hard switching to Code First from a Model First approach. Some steps and images down below:
Display all files at the project level and expand the EDMX file. You will notice that the EDMX file has a .TT file which will have several files nested, the Model Context and POCO clases between them as .cs or .vb classes (depending on the language you are using). See image down below:
Unload the project, right click and then edit.
See the image below, notice the dependencies between the context and the TT file
Remove the dependencies, the xml element should look like the image below:
Repeat the procedure for the Model classes (The ones with the model definition)
Reload your project, remove the EDMX file(s)
You will probably need to do some tweeks and update names/references.
I did this a few times in the past and it worked flawlessly on production. You can also look for tools that do this conversion for you.
This might be a good opportunity for you to rethink the architecture as well.
BTW: Bullet point 4 shouldn't be a show stopper for you. You can map/use Stored Procedures via EF. Look at the following link:
How to call Stored Procedure in Entity Framework 6 (Code-First)?
It also seems like quite a people who have gone this route [multiple contexts] regret it.
I'm not one of them.
Your core problem is a context that gets too large. So break it up. I know that inevitably there will be entities that should be shared among several contexts, which may give rise to duplicate class names. An easy way to solve this is to rename the classes into their context-specific names.
For example, I have an ApplicationUser table (who hasn't) that maps to a class with the same name in the main context, but to a class AuthorizationUser in my AuthorizationContext, or ReportingUser in a ReportingContext. This isn't a problem at all. Most use cases revolve around one context type anyway, so it's impossible to get confused.
I even have specialized contexts that work on the same data as other contexts, but in a more economical way. For example, a context that doesn't map to calculated columns in the database, so there are no reads after inserts and updates (apart from identity values).
So I'd recommend to go for it, because ...
Is there a way to combine code-first and database-first in the same context?
No, there isn't. Both approaches have different ways of building the DbModel (containing the store model, the class model, and the mappings between both). In a generated DbContext you even see that an UnintentionalCodeFirstException is thrown, to drive home that you're not supposed to use that method.
mostly related to insert/update/delete stored procedure mapping
As said in another answer, mapping CUD actions to stored procedures is supported in EF6 code-first.
I got here from a link in your comment on a different question, where you asked:
you mentioned that code-first & database-first is "technically possible" could you explain how to accomplish that?
First, the context of the other question was completely different. The OP there was asking if it was possible to use both database-first and code-first methodologies in the same project, but importantly, not necessarily the same context. My saying that it was "technically possible" applies to the former, not the latter. There is absolutely no way to utilize both code-first and database-first in the same context. Actually, to be a bit more specific, let's say there's no way to utilize an existing database and also migrate that same database with new entities.
The terminology gets a bit confused here due to some unfortunate naming by Microsoft when EF was being developed. Originally, you had just Model-first and Database-first. Both utilized EDMX. The only difference was that Model-first would let you design your entities and create a database from that, while Database-first took an existing database and created entities from that.
With EF 4.1, Code-first was introduced, which discarded EDMX entirely and let you work with POCOs (plain old class objects). However, despite the name, Code-first can and always has been able to work with an existing database or create a new one. Code-first, then is really Model-first and Database-first, combined, minus the horrid EDMX. Recently, the EF team has finally taken it a step further and deprecated EDMX entirely, including both the Model-first and Database-first methodologies. It is not recommended to continue to use either one at this point, and you can expect EDMX support to be dropped entirely in future versions of Visual Studio.
With all that said, let's go with the facts. You cannot both have an existing database and a EF-managed database in a single context. You would at least need two: one for your existing tables and one for those managed by EF. More to the point, these two contexts must reference different databases. If there are any existing tables in an EF-managed database, EF will attempt to remove them. Long and short, you have to segregate your EF-managed stuff from your externally managed stuff, which means you can't create foreign keys between entities in one context and another.
Your only real option here is to just do everything "database-first". In other words, you'll have to just treat your database as existing and manually create new tables, alter columns, etc. without relying on EF migrations at all. In this regard, you should also go ahead and dump the EDMX. Generate all your entities as POCOs and simply disable the database initializer in your context. In other words, Code-first with an existing database. I have additional information, if you need it.
Thank you to everyone for the well thought out and thorough answers.
Many of these other answers assume that the stored procedure mappings in EF Code-First work the same, but they do not. I'm a bit fuzzy on this as it's been about 6 months since I looked at it, but I believe as of EF 6.3 code first stored procedures require that you pass every column from your entity to your insert/update stored procedure and that you only pass the key column(s) to your delete procedure. There isn't an option to pick and choose which columns you can pass. We have a requirement to maintain who deleted a record so we have to pass some additional information besides just a simple key.
That being said, what I ended up doing was using a T4 template to automatically generate my EDMX/Context/Model files from the database (with some additional meta-data). This took our developer time experience down from 1.5 minutes to about 5 seconds.
My hope is EF stored procedure mappings will be improved to achieve parody with EDMX and I can then just code-generate the Code-First mappings and remove the EDMX generation completely.

Entity Framework 5 with existing DB, use generated POCO's? Move POCO's into it's own project?

I have a project with an existing database which was initially created for a legacy application. It works fine, but over time quite a few of the tables / fields have been lost or under-utilized, but the historical data MAY be useful someday so they're not going anywhere.
Enter 2012 ('13) and Entity Framework 5, an ORM with built in POCO generation (Nice Add!). So bang.. Get a connection to the Oracle Database, gen. up a context and some POCO's.. suh-weet!! But wait.. my POCO's arent really the POCO's I would like to deal with... There's a bunch of fields which i dont need anymore (not to say I'll NEVER need them, but i can't know for sure), so now i've got these POCO's which are basically bloated table mappers... So what should I do.
I see a few solutions here..
1). I could throw them around and only use the fields that I need.
2). I could get into the Model Surface and start axing the unused fields.
3). "Code-First" approach and tie the objects into the existing DB, it's a large DB though (i'm pretty sure this is possible, right?)
4). Create my own POCO / DTO's in it's own model project and these will essentially become my "domain model", but the mapping back into the context could be painful..
Lastly, do these POCO's / DTO's need to be in their own project?? What is there REALLY to gain.. seeing things like "YAGNI", i feel like it can sit right under the .edmx and never bother anyone..
On a side note, i will be needing a few of these via JSON too, so the whole serializable ability needs to be considered..
Can i just partial class the generated POCO's and only "Attribute" the properties I'll be needing?
anyhow, it'd be great to hear from past experience, or thoughts on the matter..
I could see this being in Programmers, but i figured I'd start it here.
We have a very similar situation, a large legacy DB2 database of which we need small portions of specific tables for our applications.
To do this we used entity framework code first models for the relevant subsections of data we were interested in. This meant we could do a few important things:
remove irrelevant data from the model to make code more discoverable
rename fields inside our model and map them to names that make sense in the app rather than existing column names
reduce the volume of data pulled back by queries (ie our selects dont grab all the extra bits)
where 2 formats of data exist use the modern standard rather than historical format
This works out really well for us, however a couple of things to note:
if you are writing make sure you include all required fields in the model
you can generate you CF classes but you will have to trim them a bit
generating from non mssql can sometimes be more tricky
In terms of json serialisation we do this too however we use a different model for this and use automapper to translate. You should in most cases be able to serialise without needing to add extra attributes but if they are required you can just add them to your pocos alongside any ef attributes.

Can a project have two different EF data models that reference the same table?

I've system that has a primary data model to perform most of the work.
The model has quite a few tables and with performance in mind when I came to add an administrative feature to the application I decided to use a second separate data model.
All works well until my second data model needs to access a table that is also in the primary data model. Now, from digging around I can see this can cause problems.
The two possible workaround I've come up with are to either:
Put the data models in separate projects.
Use views / stored procedures for accessing the table in question when required.
Method 1 seems the simpliest but I'm concerned about whether there would be any performance loss. Method 2 seems a bit messy and takes the point out of using EF.
Before I plump for using method 1, is there an easier work around that I could use?
In the end I decided to put the two data models into separate projects and I've there hasn't been any slowdown that I've been able to notice (I've not done any benchmarking but it's passed the perception test).
In one of her online tutorials EF guru Julie Lerman says that you should put your data model in a separate project anyway, so I don't think this has been a bad workaround.
I am working with 2 models in the same project, because I connect to 2 different databases. I have put different namespaces using "Custom Tool Namespace" on *.tt files but it is not necessary. It generally works, but it cannot handle situation when the entity (table) with the same name is in both models. When you save one model the entity with the same name is deleted from the second model.

Design Decision: Multiple EF EDMX Files

If you have used the Entity Framework then you know the EDMX is cool. You also know it can become HUGE and almost unmanageable.
When it gets large, it is tempting to create a second EDMX or third - even one for each Schema in your database (just as an example).
Such a seperation would help with organization of your EDMX, but it could seperate the context of entities in the same namespace.
Moreover, seperate EDMX files can create a situation where a JOIN operation across EDMX files results in excessive, redundant database communication.
But, the fact remains, the larger the EDMX, the more difficult it is to use. The more difficult it is to ensure it is correct. The easier it is to break.
Do you break your EDMX files apart? Do you have a rule of thumb for when to it?
One example for the need to split your EDMX would be
if you have a group of entities that are used in more than one project,
while others are project-specific and you are willing to forsake having navigation properties between the parts (and remain with only exposed FKs).
You can automatically merge the EDMXs into one if you want to maintain the separately, but open up a context to them all and query as one. This requires that they share the same namespace.
We've only gone as far as needing to use two separate EDMX in a single solution. This separation occurred for us with an EDMX for domain specific model entities and another for those more common across all of our solutions (Payment as an example). Logically you could say this for us was at the db schema level although that wasn't the hard rule of the separation.
Whilst we didn't have a requirement for joins across them we did need transactions. We accomplished this with a reusable UnitOfWorkContainer that would wrap the EF contexts within a TransactionScope. The contexts would be injected through DI into the container and we would only use the TransactionScope if there was more than one context held in the container.
The container itself implemented our IUnitOfWork interface so it was dead easy to plug into the existing codebase.

Is it possible to have multiple Entity Framework edmx's with a shared connection string?

My concept is to have a logging/audit edmx file with corresponding mapped types defined in one project. This edmx has concepts and classes like AuditTrail and PropertyChange
A second edmx for the actual application models, domain if you will, with classes like Product, Category, and Order.
What I want to do is "scoop up" the first auditing edmx file into the second domain edmx. The schema information is 100% the same, the database has tables from both.
What I want to have happen is that these two edmx files are combined in such a way that I can use a transaction to save data such as both are dependent on each other finishing. My audit information can't save without my domain information and vice versa.
I've been goggling around and this seems possible I'm just missing some implementation detail thats not bringing this together.
This should be as simple as pointing the domain edxm and objectcontext connection string to the auditing edmx's csdl, ssdl, and msl files? The goal would be to load all of the MetaData information inside a single instance of an ObjectContext so I can wrap a call to both with a transaction.
This is what I have in my connection string for the web app/domain part of this application:
connectionString="metadata=res://*/Models.CfarModels.csdl|
res://*/Models.CfarModels.ssdl|
res://*/Models.CfarModels.msl|
W:\map\AuditModels.csdl|
W:\map\AuditModels.ssdl|
W:\map\AuditModels.msl;
Am I on the right track here is is this impossible?
While it is possible to load multiple CSDL files into one (Entity)Connection, it is not possible to load multiple MSL or SSDL files, because these are completely self-contained.
Back to the CSDL, there is a rarely used <using> element in CSDL. Which might give the impression that it is similar to a Reference in .NET, but actually it is more like a Merge.
I.e. one CSDL in another actually modifies both, merging them together, and potentially invalidates MSL's and SSDL's, by making them incomplete.
So back to your scenario:
You could in theory have 2 CSDLs:
1) To describe the Audit types
2) That uses (1) & defines the Domain Types and defines EntitySets and AssociationSets for both kinds of types.
You would then have one mapping file to map (2) and a storage model file too.
Which would leave you with something like this:
"metadata=res://*/Models.CfarModels.csdl|
res://*/Models.CfarModels.ssdl|
res://*/Models.CfarModels.msl|
W:\map\AuditModel.csdl;
Personally though I don't think you gain enough from this separation to make it worthwhile, most of the metadata is in the extents, the mapping and the storage model anyway, so type re-use while nice is only about 20% of the work anyway.
All you can really re-use is the audit type definitions, but that probably isn't worth the effort.
Hope this helps
Alex James
Microsoft.