EF 4.1: Removing child object from collection does not delete it - why?

天涯浪子 提交于 2019-12-19 08:05:33

问题


I have a some error : EF 4: Removing child object from collection does not delete it - why?

when i remove a child from the parent that the child is deleted when i call SaveChanges(), it gives the follow error message:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

But with DbContext and EF 4.1, the "context.DeleteObject(recipe)" does not exist.

Any suggestion ?

[EDIT]

    public void UpdateWithAttributes(Model model, IEnumerable<Entity> entities)
    {
        var modelOriginal = this.unitOfWork.Model.GetById(model.IModel);

        this.unitOfWork.Context.Entry(modelOriginal).CurrentValues.SetValues(model);
        UpdateEntityAttributeAssociations(modelOriginal, entities);

        this.unitOfWork.Commit();
    }

    public void UpdateEntityAttributeAssociations(Model model, IEnumerable<Entity> current)
    {
        unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load();
ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary

        // delete
        if (original != null)
        {
            List<Entity> toDelete = GetToDelete(original, current);

            foreach (Entity originalEntityToDelete in toDelete)
            {
                unitOfWork.Context.Entity.Remove(originalEntityToDelete);
            }
        }

        // add, update
        if (current != null)
        {
            foreach (Entity currentEntity in current)
            {
                // No need to set the UpdatedWhen. The trigger on the table will handle that.
                if (original.Where(originalEntity => originalEntity.IEntity == currentEntity.IEntity).FirstOrDefault() == null)
                {
                    model.Entities.Add(currentEntity);
                }
            }
        }
    }

回答1:


I guess that you are adding again what you have just deleted because removing from the DbSet also removes internally the entity from the child collection original. Then in the second loop you add the entity again. You could try to catch this situation like so:

public void UpdateEntityAttributeAssociations(Model model,
                                              IEnumerable<Entity> current)
{
    unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load();
    ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary

    // delete
    List<Entity> toDelete = null;
    if (original != null)
    {
        toDelete = GetToDelete(original, current);
        foreach (Entity originalEntityToDelete in toDelete)
        {
            unitOfWork.Context.Entity.Remove(originalEntityToDelete);
        }
    }

    // add, update
    if (current != null)
    {
        foreach (Entity currentEntity in current)
        {
            if (toDelete == null || !toDelete.Contains(currentEntity))
            {
                if (original.Where(originalEntity => originalEntity.IEntity == 
                               currentEntity.IEntity).FirstOrDefault() == null)
                {
                    model.Entity.Add(currentEntity);
                }
            }
        }
    }
}

I've also replaced your first line with explicit loading the child collection since your procedure to query the child entities manually looks unfamiliar to me, but I don't think that this is the problem (but I don't know).

Edit

I'm not sure if my code above helps to remove the exception you had. I don't know what happens if you add an entity to a collection which is already in Deleted state and if this could throw this exception.

If the code doesn't help you could test if you also have the problem without the second (the Insert) loop. And how looks GetToDelete exactly? And how look your Model and Entity class and their relationships? And is model.Entity indeed another collection than model.Entities (or is it a typo)?




回答2:


You have to call:

context.Recipes.Remove(recipe);

Where Recipes are DbSet<Recipe>.



来源:https://stackoverflow.com/questions/6125871/ef-4-1-removing-child-object-from-collection-does-not-delete-it-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!