In my last project I have used Entity Framework 5 Code First. I completed my project but had a lot of pain during the development process.
I tried to explain my pain below:
I had several data classes in my data access logic layer like Product, ProductCategory, Order, Company, Manufacturer etc... Each class has some references to some other classes. For example, a Product instance has a ProductCategory property.
Inside Add and Update methods of my Data Access Object classes I set the states of each property (other than the primitive types) to Unchanged or Modified in the context. Below is some part of an update method of some dao class:
context.Entry(entity).State = System.Data.EntityState.Modified;
if (entity.Category != null)
context.Entry(entity.Category).State = System.Data.EntityState.Unchanged;
if (entity.Manufacturer != null)
context.Entry(entity.Manufacturer).State = System.Data.EntityState.Unchanged;
foreach (var specificationDefinition in entity.SpecificationDefinitions)
{
context.Entry(specificationDefinition).State = System.Data.EntityState.Unchanged;
foreach (var specificationValue in specificationDefinition.Values)
{
context.Entry(specificationValue).State = System.Data.EntityState.Unchanged;
}
}
This code goes like this. Some of my add or update methods are about 30 lines of code. I think I am doing something wrong, adding or updating an entity should not be this much pain but when I don't set the states of the objects I either get exception or duplicate entries in the database. Do I really have to set the state of each property that maps to database?
Ok, you're just doing something wrong then. In addition to my comment, I've created a sample for your which shows that EF doesn't create duplicates by default.
I have two classes:
One context:
Then one initializer class (this could inherit from other strategies if you want):
The main program:
This results in the following console output:
Also, when looking in SQL Server Management Studio, this solution has only created (and updated) one product and one category.
Ofcourse, you should work with repositories to retrieve, update and delete your data and a unit of work. These have been left out of the example.
So, if you do not post any code, we can't help you much further :-)
You can replace your code by:
The reason why this is the same (unless the related entities were already attached to the context in another state than
Unchanged
before) is thatAttach
putsentity
including all related entities in the object graph into the context in stateUnchanged
. Setting the state toModified
afterwards forentity
only changes the state of the product alone (not the related entities) fromUnchanged
toModified
.