EF 4.1:从集合中删除子对象不会删除它 - 为什么?

发布于 2024-11-09 19:23:37 字数 1910 浏览 3 评论 0原文

我有一些错误: EF 4:从集合中删除子对象不删除它 - 为什么?

当我从父级中删除子级时,当我调用SaveChanges()时,该子级被删除,它会给出以下错误消息:

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当关系发生更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

但对于 DbContext 和 EF 4.1,“context.DeleteObject(recipe)”不存在。

有什么建议吗?

[编辑]

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑶笙 2024-11-16 19:23:37

您必须调用:

context.Recipes.Remove(recipe);

其中 RecipesDbSet

You have to call:

context.Recipes.Remove(recipe);

Where Recipes are DbSet<Recipe>.

梦里兽 2024-11-16 19:23:37

我猜您正在再次添加刚刚删除的内容,因为从 DbSet 中删除也会从内部删除子集合 original 中的实体。然后在第二个循环中再次添加实体。您可以尝试像这样捕获这种情况:

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

我还用显式加载子集合替换了您的第一行,因为手动查询子实体的过程对我来说看起来很陌生,但我不认为这是问题所在(但我不知道)。

编辑

我不确定上面的代码是否有助于消除您遇到的异常。我不知道如果将一个实体添加到已处于“已删除”状态的集合中,以及是否会引发此异常,会发生什么。

如果代码没有帮助,您可以测试在没有第二个(插入)循环的情况下是否也遇到问题。 GetToDelete 到底是什么样子的?您的 ModelEntity 类及其关系如何? model.Entity 确实是 model.Entities 之外的另一个集合吗(或者是一个拼写错误)?

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文