EF 4.1:从集合中删除子对象不删除它 - 为什么? [英] EF 4.1: Removing child object from collection does not delete it - why?

查看:701
本文介绍了EF 4.1:从集合中删除子对象不删除它 - 为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些错误: <一href="http://stackoverflow.com/questions/2554696/ef-4-removing-child-object-from-collection-does-not-delete-it-why">EF 4:删除子对象从集合并不会删除它 - 为什么

当我删除一个孩子,当我叫孩子被删除父的SaveChanges(),它提供了如下错误信息:

  

操作失败:关系无法改变,因为一个或一个以上的外键的属性是不可为空。当做出改变有关系,相关的外键属性设置为空值。如果外键不支持空值,一个新的关系必须定义,外键属性必须指定一个非空值,或者不相关的对象必须被删除。

但随着的DbContext和EF 4.1中,context.DeleteObject(配方)不存在

任何建议?

 公共无效UpdateWithAttributes(型号机型,IEnumerable的&LT;实体&GT;实体)
    {
        VAR modelOriginal = this.unitOfWork.Model.GetById(model.IModel);

        this.unitOfWork.Context.Entry(modelOriginal).CurrentValues​​.SetValues​​(模型);
        UpdateEntityAttributeAssociations(modelOriginal,实体);

        this.unitOfWork.Commit();
    }

    公共无效UpdateEntityAttributeAssociations(型号机型,IEnumerable的&LT;实体&GT;电流)
    {
        unitOfWork.Context.Entry(模型).Collection(M =&GT; m.Entities).Load();
ICollection的&LT;实体&GT;原= model.Entities; //也许.ToList()必要

        // 删除
        如果(原创!= NULL)
        {
            名单&LT;实体&GT; toDelete = GetToDelete(原件,电流);

            的foreach(实体originalEntityToDelete在toDelete)
            {
                unitOfWork.Context.Entity.Remove(originalEntityToDelete);
            }
        }

        //添加,更新
        如果(电流!= NULL)
        {
            的foreach(实体currentEntity电流)
            {
                //无需设置UpdatedWhen。上表中的触发器会处理的。
                如果(original.Where(originalEntity =&GT; originalEntity.IEntity == currentEntity.IEntity).FirstOrDefault()== NULL)
                {
                    model.Entities.Add(currentEntity);
                }
            }
        }
    }
 

解决方案

我猜你要添加一次你刚才被删除,因为从删除 DbSet 内部也删除从子集实体。然后在第二回路再次添加的实体。你可以尝试赶上这种情况下,像这样:

 公共无效UpdateEntityAttributeAssociations(型号机型,
                                              IEnumerable的&LT;实体&GT;当前)
{
    unitOfWork.Context.Entry(模型).Collection(M =&GT; m.Entities).Load();
    ICollection的&LT;实体&GT;原= model.Entities; //也许.ToList()必要

    // 删除
    名单&LT;实体&GT; toDelete = NULL;
    如果(原创!= NULL)
    {
        toDelete = GetToDelete(原件,电流);
        的foreach(实体originalEntityToDelete在toDelete)
        {
            unitOfWork.Context.Entity.Remove(originalEntityToDelete);
        }
    }

    //添加,更新
    如果(电流!= NULL)
    {
        的foreach(实体currentEntity电流)
        {
            如果(toDelete == NULL ||!toDelete.Contains(currentEntity))
            {
                如果(original.Where(originalEntity =&GT; originalEntity.IEntity ==
                               currentEntity.IEntity).FirstOrDefault()== NULL)
                {
                    model.Entity.Add(currentEntity);
                }
            }
        }
    }
}
 

我也换成你有明确的加载子集合,因为你的程序手动查询子实体看起来生疏了第一线,但我不认为这是问题(但我不知道)

修改

我不知道如果我的code以上,有助于消除你有例外。我不知道如果你添加一个实体的集合这已经是删除状态,如果这可以抛出此异常会发生什么。

如果在code并不能帮助您可以测试,如果你也有问题,而第二(插入)循环。而如何看起来 GetToDelete 到底是什么?而如何照顾你的型号实体类和它们的关系?而且是 model.Entity 的确是另一个集合比 model.Entities (或者是一个错字)?

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);
                }
            }
        }
    }

解决方案

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)?

这篇关于EF 4.1:从集合中删除子对象不删除它 - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆