C# Entity Framework

Replacing child collections in Entity Framework

ORMs are nice. Usually. That is, until you hit a mostly unhelpful exception like “An object with the same key already exists in the ObjectStateManager”. I ran into this problem by trying to do a complete replacement of an entity’s child entity collection (i.e. a Products’s IQueryable<Ingredient>). To do this, you actually need to remove all of the entities from the IQueryable that need to be removed, and then add the new entities. After some frustration, I created the following extension to help me out.

public static void ReplaceEntityCollection<T, K>(this ICollection<T> startingCollection, ICollection<T> newCollection,
                                Func<T, K> selector )
{
    var newItemCompareValues = newCollection.Select(selector);
    var existingItemCompareValues = startingCollection.Select(selector);

    var alternativeItemsToRemove = startingCollection.Where(at => !newItemCompareValues.Contains(selector(at)));
    var alternativeItemsToAdd = newCollection.Where(at => !existingItemCompareValues.Contains(selector(at)));

    foreach (var alternativeItemToRemove in alternativeItemsToRemove)
    {
        startingCollection.Remove(alternativeItemToRemove);
    }

    foreach (var alternativeItemToAdd in alternativeItemsToAdd)
    {
        startingCollection.Add(alternativeItemToAdd);
    }
}

Now, I can do the following:

myProduct.Ingredients.ReplaceEntityCollection(myNewIngredients, ((Ingredient i) => i.Id));

This seems to have resolved that issue! On to the next.

Leave a Reply

Your email address will not be published. Required fields are marked *