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.
I'm trying to implement EF TPH using the "Database First" with the help of the following document from Microsoft,
http://msdn.microsoft.com/en-us/data/jj618292.aspx
I do understand how this works but it sounds a little naive the way it's done or I'm missing something which I would like someone to enlighten me on this.
To my understanding, the whole point of implementing a database first approach is when you have a pre-exisiting database or if you prefer to do your work first hand on your database and work your way up, however, this document suggests that the inheriting tables (Student, Instructor) are meant to be created at the EF design area using a field on the base class which they call a "Discriminator" field which your inherited entities end up pointing to.
However, my question is, why would you have to create these inherited table at the ER designer where you initially intended to create your table structure first hand before working your way up the entity framework and how would this change that you applied on the ER designer (adding the inherited tables) be mapped into the back-end database, and at the end of the day when I want to make a change to my database later on, where will I have to make these changes (on MS SQL or the ER designer). If I end up adding tables from the ER end, then that would pretty much defeat the purpose of the "Database First" methodology, because I basically ended up using the procedures in the "Model First" approach which doesn't make sense at all.
Your help in clearing this up would be much appreciated.
PLEASE NOTE: I would rather have everything done at my database and rather not use the "Model First" approach. I'm interested to implement the TPH and be able to make any changes directly to my database and have those changes mapped into my EF sublayer (not the other way around).
Many Thanks
I don't see how EF could ever infer inheritance for you. Maybe it would be possible to have it triggered it by a field explicitly named "Discriminator" in a table, but what if you want a different name for the discriminator? And then, what should be the names of the derived classes? EF has no clue. The names are nowhere in the data model.
Still, it is database first. But EF just creates a first draft of the mapping. Nearly always you need to make modifications to the conceptual model (the model you see in the edmx), like renaming properties or classes, renaming/adding/removing associations. Or applying inheritance. When you update the the model from the database it may be necessary to apply some more manual changes. For instance, with TPH inheritance you may have to decide in which class to put a new field.
Maybe you are a bit side tracked by the idea that you "have to create these inherited tables at the ER designer". You define classes that map to one and the same table.
I did work on ADO.NET Entity Framework v2 about two years ago. I have faint memories.
Incidentally, I happen to be working in a very secured (for want of a euphemism) environment where a lot of links are blocked and there's not much one can do. It does get in the way of studying and working, more than a bit.
Therefore, I have to rely on this forum for a few basic questions I have to get started again. This time, I am working on Entity Framework 4. Here are my questions.
All these questions relate to the EDM generated entities, i.e. not the Code First model.
1) Is my understanding correct? I can rename any column name in the EDM designer generated model and nothing breaks.
2) Foreign keys are expressed as navigational properties in the generated entity classes. No special consideration is required to maintain foreign key relationships. I recall in version 1 of EF, you had just ID properties and the navigational IQueryable/IEnumerable/EntityCollection/RelatedEnd properties were introduced in version 2. I just need to know if I need to do anything to retain/maintain foreign key relationships and referential data integrity. I assume I don't need to. A confirmation would be nice.
3) What are all the possible ways to execute a stored procedure? I recall -- one way to use ExecuteSQL or something on the Context.Database object, another to use EntityClient API and the third was to specify stored procedure names in the InsertCommand, SelectCommand, etc. thingies in the mapping window of the EDM designer. Is this correct?
4) How do you use those SelectCommand thingies in the mapping window on an entity? Do you just supply the names of the stored procedures or user defined SQL functions?
5) How do I create an entity out of a subset of a table? Do I just create an entity from the table and then delete the columns I don't need from the designer? What happens if there are required (NOT NULL in SQL) values that are not in the subset I choose?
6) How do I create a table out of a query or join of two or more tables.
1) You can rename columns in the designer and nothing should break (if the name is valid)
2) Navigation properties point to related entities. In EF4 foreign keys were added. Foreign key properties basically expose the database way of handling relations. However, they are helpful since you don't have to load related entities just to change relationship - you can just change the key value to the id of the other entity and save your changes
3) Yes. You can either execute the procedure directly - this is for stored procedures that are not related to CUD (Create/Update/Delete) operations. You can map CUD operations to stored procedure as opposed to having EF execute SQL statements it came up with for your CUD operations.
4) I think this is a bit out of scope - you probably can find a lot of blogs with images how to do it. Any decent book on EF should also have a chapter (or two) on this. Post a question to stackoverflow if you hit a specific problem.
5) Remove properties in the designer and then supply default value to the S-Space definition. I believe you cannot do this with the designer. You need to rightclick on the edmx file and open it with the Xml editor and manually edit it. Also see this: Issue in EF, mapping fragment,no default value and is not nullable
6) You can either create a view in the database or you can create entity set using E-SQL in your edmx file (I think this will be read only though) or you may be able to use Entity Splitting. Each of these is probably a big topic itself so I think you should find more about these and come back if you have more specific questions / problems
It appears to me that a strange phenomenon is occurring with inherited entities (TPT) in EF4.
I have three entities.
1. Asset
2. Property
3. Activity
Property is a derived-type of Asset.
Property has many activities (many-to-many)
When modeling this in my EDMX, everything seems fine until I try to insert a new Property into the database. If the property does not contain any Activity, it works, but all hell breaks loose when I add some new activities to the new Property.
As it turns out after 2 days of crawling the web and fiddling around, I noticed that in the EF store (SSDL) some of the constraints between entities were not picked up during the update process.
Property_Activity table which links properties and activities show only
one constraint
FK_Property_Activity_Activity but
FK_Property_Activity_Property was
missing.
I knew this is an Entity Framework anomoly because when I switched the relationship in the database to:
Asset <--> Asset_Activity <--> Activity
After an update, all foreign key constraints are picked up and the save is successful, with or without activities in the new property.
Is this intended or a bug in EF?
How do I get around this problem?
Should I abandon inheritance altogether?
Not a but but a poor visual designer.
Its generally best to simply manage the Entity XML by hand.
No inheritance works well for many situations.
Basically I use the update from database in the visual designer but knowing that the designer has its quirks. I have simply used the update from database to stub out the basics of what I want. Then I go into the Entity XML my self and clean it up the way I want. Just of note Complex types are a pain with the designer. If you plan to use complex types get ready to learn your Entity XML well.
I am getting an error 3007 when I add my entity model to my solution.
I found these links:
Good explination
Short answer
About this error:
Error 1 Error 3007: Problem in Mapping
Fragments starting at lines 89, 94:
Non-Primary-Key column(s) [Person_ID]
are being mapped in both fragments to
different conceptual side properties -
data inconsistency is possible because
the corresponding conceptual side
properties can be independently
modified.
Their Answer: I agree with their conclusion that by simply deleting the Scalar Property Person_ID and leave the Navigation Property my problem is fixed. However this is not very scalable since I am dynamically building my database and my entity is updated very often. I dont want to have to go through and clean up my entity every time I update it.
My Question: Is there a way to fix the error by correcting the way EF builds the entity? Or is there a way to remove the Scalar Property through code? Perhaps there is even a few options that I am overlooking.
Try to remove foreign property column from Entity set using entity model design it will solve your problem
For example
We have two tables one is customer and other one is order, using entity model design we added association between customers and orders when we do this Ado.net entity framework i will add navigation properties to both below tables.
Like
Customer.Orders - Here order is list
Order.Customer
One - Many relation.
So we need to remove property from with name CustomerId[Foreign key column] from Order entity set.
For reference:
http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/2823634f-9dd1-4547-93b5-17bb8a882ac2/
My experience with EF v1 is similar to yours. When the EDM is generated incorrectly and you can't work around the issue, you have to manually edit the EDM. EF v.Next (Entity Framework v4 I believe) will support "Code Only" Entity Data Models, and the EDM designer is supposed to be much better. One or the other improvement should make our lives easier. Until then...