2

If I have Book object which has a child collection of Comments, Can I update the Book and list of Comments together with entity framework?

I have tried :

_context.Books.Attach(book);
_context.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
_context.SaveChanges();

with no luck...

getting the following error on the first line:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key

Nate
  • 28,586
  • 21
  • 107
  • 177
stephen776
  • 8,546
  • 13
  • 66
  • 118
  • "with no luck" isn't very descriptive. What *exactly* happens when you try it? – Ryan Lundy Apr 28 '11 at 17:04
  • I am getting the error: 'An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key' – stephen776 Apr 28 '11 at 17:12
  • On which line? The `Attach` line? – Ryan Lundy Apr 28 '11 at 17:17
  • Did you `Detatch` the book before you tried to `Attach` it? i.e. can you show the code before this... – Ian Mercer Apr 28 '11 at 17:25
  • I did not try to detach the book first...Those are the only three lines in my method right now..passing the book object in as a parameter. I am new to EF, as you can tell... – stephen776 Apr 28 '11 at 17:35
  • And where do you create context? Is it the same context used to load the book? If yes you have your problem: http://stackoverflow.com/questions/3653009/entity-framework-and-connection-pooling/3653392#3653392 Don't reuse context. – Ladislav Mrnka Apr 28 '11 at 19:40
  • the context is injected via Ninject when I instantiate my repo class(also using the UnitOfWork pattern as described here... http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx ) – stephen776 Apr 29 '11 at 11:16

1 Answers1

2

More than likely you have a circular dependency (Books has a foreign key reference to Comments, and Comments back to Books). In this case, the UpdateTranslator within EF is unable to determine the dependency order. As far as I can tell, in this model of development, there is no way to pass a hint to EF to indicate what the order is.

The most common way to solve this (that I have seen) is to do a two-phase commit. Make a change to the Book, save it, then make a change to Comments, and save that. I have found that using the Code First approach allows you to be more specific about the relationships and thereby fix many of the problems that I've had.

Edit:
Here's an example:

using (var context = new BookContext())
{
    book.Title = "This is the new title";
    context.SaveChanges();

    book.Comments.Add(new Comment("This is a comment"));
    context.SaveChanges();
}

If there is a circular dependency, you could not do the above with a single call to SaveChanges.

Bobby D
  • 2,080
  • 14
  • 21
  • if the code I posted above is attempting to do everything in one call, how can I modify it to split it up into 2 parts? – stephen776 Apr 28 '11 at 17:46
  • I am not certain I actually have a circular dependency...My Comment object has a BookID property, and my Book object has a Comments Navigation property...There is definitely not a circular dependency within the DB itself – stephen776 Apr 29 '11 at 11:25
  • Have you tried doing two separate `SaveChanges` to see if that resolves the issue? It would be difficult to debug further without a better view of the model. – Bobby D Apr 29 '11 at 13:17