How to use DBContext.Add/Attach (using EF CodeFirst 4.1) with nested opbjects

Problem: When adding an object "Order" to my dbcontext, all nested objects of the order gets "readded" to the database, though the nested objects is static data and only a reference shoudl be added in the database.

Example: The database holds 0 orders, and 3 items.

I add one order with 2 items.

Now the database hold 1 order, and 5 items. The two items in the order has been "readded" to the database, even though the items had the right primary keys before db.SaveChanges().

I realize that i may be able to attach the existing items to the dbcontext before saving changes, but is that really the only way to go? Can't EF figure out that to item already exists when the primary key matches an existing item?

Does anyone know if this is different in the new version of EF CodeFirst?

Answers


No EF cannot figure if entities are existing one or new one - both Add and Attach commands are graph oriented operations. You call them on one entity in the graph and they traverse all relations (and their relations and so on) and perform the operation for them as well.

You must figure correct state of each entity in the graph for example by using:

dbContext.Orders.Add(newOrder);
foreach(var item in newOrder.Items) {
    dbContext.Entry(item).State = EntityState.Unchanged;
}
dbContext.SaveChanges();

You can use the reverse operation by calling Attach(newOrder) and set the order to Added state. The main difference will come with independent associations (for example many-to-many relations). The first approach will correctly add new relation between order and each item whereas second will not unless you manually set each relation to Added state (and changing state for relations is more complex).


Need Your Help

Requesting User Input to Name the File being created using ofstream C++ MFC

c++ visual-studio-2012 mfc

How would you go about giving the user the ability to change the Name of the ofstream File using c++ MFC. I would like to add an Edit Control Box that will give the user an ability to Type in the ...

How to use CanCan with Grape?

ruby-on-rails ruby ruby-on-rails-4 cancan grape-api

I wanna use CanCan for authorization in my API. How can I use, for example, the authorize! method from Grape::API module? For now, when I'm trying to use it, it returns me this:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.