Take the 2-minute tour ×

I am getting this error when I GetById() on an entity and then set the collection of child entities to my new list which comes from the MVC view.


I don't quite understand this line:


Why would I change the relationship between 2 entities? It should remain the same throughout the lifetime of the whole application.

The code the exception occurs on is simple assigning modified child classes in a collection to the existing parent class. This would hopefully cater for removal of child classes, addition of new ones and modifications. I would have thought Entity Framework handles this.

The lines of code can be distilled to:

var thisParent = _repo.GetById(1);
thisParent.ChildItems = modifiedParent.ChildItems();
share|improve this question

6 Answers 6

up vote 59 down vote accepted

You should delete old child items thisParent.ChildItems one by one manually. Entity Framework doesn't do that for you. It finally cannot decide what you want to do with the old child items - if you want to throw them away or if you want to keep and assign them to other parent entities. You must tell Entity Framework your decision. But one of these two decisions you HAVE to make since the child entities cannot live alone without a reference to any parent in the database (due to the foreign key constraint). That's basically what the exception says.


What I would do if child items could be added, updated and deleted:

public void UpdateEntity(ParentItem parent)
    // Load original parent including the child item collection
    var originalParent = _dbContext.ParentItems
        .Where(p => p.ID == parent.ID)
        .Include(p => p.ChildItems)
    // We assume that the parent is still in the DB and don't check for null

    // Update scalar properties of parent,
    // can be omitted if we don't expect changes of the scalar properties
    var parentEntry = _dbContext.Entry(originalParent);

    foreach (var childItem in parent.ChildItems)
        var originalChildItem = originalParent.ChildItems
            .Where(c => c.ID == childItem.ID && c.ID != 0)
        // Is original child item with same ID in DB?
        if (originalChildItem != null)
            // Yes -> Update scalar properties of child item
            var childEntry = _dbContext.Entry(originalChildItem);
            // No -> It's a new child item -> Insert
            childItem.ID = 0;

    // Don't consider the child items we have just added above.
    // (We need to make a copy of the list by using .ToList() because
    // _dbContext.ChildItems.Remove in this loop does not only delete
    // from the context but also from the child collection. Without making
    // the copy we would modify the collection we are just interating
    // through - which is forbidden and would lead to an exception.)
    foreach (var originalChildItem in
                 originalParent.ChildItems.Where(c => c.ID != 0).ToList())
        // Are there child items in the DB which are NOT in the
        // new child item collection anymore?
        if (!parent.ChildItems.Any(c => c.ID == originalChildItem.ID))
            // Yes -> It's a deleted child item -> Delete


Note: This is not tested. It's assuming that the child item collection is of type ICollection. (I usually have IList and then the code looks a bit other.) I've also stripped away all repository abstractions to keep it simple.

I don't know if that is a good solution but I believe that some kind of hard work along these lines must be done to take care of all kinds of changes in the navigation collection. I would be happy as well to see an easier way.

share|improve this answer
So what if some are only changed? Does that mean I still have to remove them and add them again? –  jaffa Apr 4 '11 at 17:10
@Jon: No, you can also update existing items of course. I've added an example how I would probably update the child collection, see Edit section above. –  Slauma Apr 4 '11 at 18:33
@Slauma: Lol, if I knew that you are going to modify your answer I would not write my answer ... –  Ladislav Mrnka Apr 4 '11 at 19:53
@Ladislav: No, no, I am glad that you wrote your own answer. Now at least I know that it's not complete nonsense and much too complicated what I did above. –  Slauma Apr 4 '11 at 20:27
I would add a condition when retrieving the originalChildItem in the foreach: ...Where(c => c.ID == childItem.ID && c.ID != 0) otherwise it will return the newly added children if the childItem.ID == 0. –  perfect_element Mar 1 at 17:02

This is a very big problem. What actually happens in your code is this:

  • You load Parent from the database and get an attached entity
  • You replace its child collection with new collection of detached children
  • You save changes but during this operation all children are considered as added becasue EF didn't now about them till this time. So EF tries to set null to foreign key of old children and insert all new children => duplicate rows.

Now the solution really depends on what you want to do and how would you like to do it?

If you are using ASP.NET MVC you can try to use UpdateModel or TryUpdateModel.

If you want just update existing children manually, you can simply do something like:

foreach (var child in modifiedParent.ChildItems)
    context.Entry(child).State = EntityState.Modified;


Attaching is actually not needed (setting the state to Modified will also attach the entity) but I like it because it makes the process more obvious.

If you want to modify existing, delete existing and insert new childs you must do something like:

var parent = context.Parents.GetById(1); // Make sure that childs are loaded as well
foreach(var child in modifiedParent.ChildItems)
    var attachedChild = FindChild(parent, child.Id);
    if (attachedChild != null)
        // Existing child - apply new values
        // New child
        // Don't insert original object. It will attach whole detached graph

// Now you must delete all entities present in parent.ChildItems but missing
// in modifiedParent.ChildItems
// ToList should make copy of the collection because we can't modify collection
// iterated by foreach
foreach(var child in parent.ChildItems.ToList())
    var detachedChild = FindChild(modifiedParent, child.Id);
    if (detachedChild == null)

share|improve this answer
But there is your interesting remark about using .Clone(). Do you have the case in mind that a ChildItem has other sub-child navigation properties? But in that case, wouldn't we want that the whole sub-graph is attached to the context since we would expect that all the sub-childs are new objects if the child itself is new? (Well, might be different from model to model, but let's assume the case that the sub-childs are "dependent" from the child like the childs are dependent from the parent.) –  Slauma Apr 4 '11 at 20:35
It would probably require "smart" clone. –  Ladislav Mrnka Apr 4 '11 at 20:39
What if you don't want to have a Child's collection in your context? http://stackoverflow.com/questions/20233994/do-i-need-to-create-a-dbset-for-eve‌​ry-table-so-that-i-can-persist-child-entitie –  kirsten g Nov 27 '13 at 4:55

I've no idea why the other two answers are so popular!

I believe you were right in assuming the ORM framework should handle it - after all, that is what it promises to deliver. Otherwise your domain model gets corrupted by persistence concerns. NHibernate manages this happily if you setup the cascade settings correctly. In Entity Framework it is also possible, they just expect you to follow better standards when setting up your database model, especially when they have to infer what cascading should be done:

You have to define the parent - child relationship correctly by using an "identifying relationship".

If you do this, Entity Framework knows the child object is identified by the parent, and therefore it must be a "cascade-delete-orphans" situation.

Other than the above, you might need to (from NHibernate experience)


instead of replacing the list entirely.


@Slauma's comment reminded me that detached entities are another part of the overall problem. To solve that, you can take the approach of using a custom model binder that constructs your models by attempting to load it from the context. This blog post shows an example of what I mean.

share|improve this answer
Setup as identifying relationship won't help here because the scenario in the question has to deal with detached entities ("my new list which comes from the MVC view"). You still have to load the original children from the DB, find the removed items in that collection based on the detached collection and then remove from the DB. The only difference is that with an identifying relationship you can call parent.ChildItems.Remove instead of _dbContext.ChildItems.Remove. There is still (EF <= 6) no built-in support from EF to avoid lengthy code like the one in the other answers. –  Slauma May 7 '13 at 21:39
I understand your point. However, I believe with a custom model binder that loads the entity from the context or returns a new instance the approach above would work. I'll update my answer to suggest that solution. –  Andre Luus May 8 '13 at 8:23
Yes, you could use a model binder but you had to do the stuff from the other answers in the model binder now. It just moves the problem from repo/service layer to the model binder. At least, I don't see a real simplification. –  Slauma May 8 '13 at 9:19
The simplification is automatic deletion of orphaned entities. All you need in the model binder is a generic equivalent of return context.Items.Find(id) ?? new Item() –  Andre Luus May 8 '13 at 10:19
Good feedback for the EF team, but your proposed solution doesn't solve anything in EF land unfortunately. –  Chris Moschini Jul 21 at 22:56

I found this answer much more helpful for the same error. It seems that EF does not like it when you Remove, it prefers Delete.

You can delete a collection of records attached to a record like this.

order.OrderDetails.ToList().ForEach(s => db.Entry(s).State = EntityState.Deleted);

In the example, all of the Detail records attached to an Order have their State set to Delete. (In preparation to Add back updated Details, as part of an Order update)

share|improve this answer
The only working solution –  Mohsen Afshin Jun 24 at 15:20

I've tried these solutions and many others, but none of them quite worked out. Since this is the first answer on google, I'll add my solution here.

The method that worked well for me was to take relationships out of the picture during commits, so there was nothing for EF to screw up. I did this by re-finding the parent object in the DBContext, and deleting that. Since the re-found object's navigation properties are all null, the childrens' relationships are ignored during the commit.

var toDelete = db.Parents.Find(parentObject.ID);

Note that this assumes the foreign keys are setup with ON DELETE CASCADE, so when the parent row is removed, the children will be cleaned up by the database.

share|improve this answer

This type of solution did the trick for me:

Parent original = db.Parent.SingleOrDefault<Parent>(t => t.ID == updated.ID);
updated.Childs.ToList().ForEach(c => original.Childs.Add(c));

Its important to say that this deletes all the records and insert them again. But for my case (less then 10) it´s ok.

I hope it helps.

share|improve this answer
Does the reinsertion happens with new IDs or it keeps the child's IDs they had in the first place? –  Tony May 5 at 22:14

Your Answer


