是否可以从收集中删除小孩并解决SaveChanges上的问题? [英] Is it possible to remove child from collection and resolve issues on SaveChanges?

查看:109
本文介绍了是否可以从收集中删除小孩并解决SaveChanges上的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用实体框架代码首先与外键关系。我们调查在我们的应用程序中处理从实体ICollection中移除对象的方法。

We are using Entity Framework Code First with Foreign Key relationships. We investigating on ways on handling removing objects from an entities ICollection in our application.

当我们有一个具有子关系的实体时,我们可以使用Add方法将对象直接添加到它们的ICollection。现在当你使用删除你得到错误

When we have an entity with child relationships we can add objects directly to their ICollection using Add method. Now when you use remove you get the error


发生System.InvalidOperationException消息=操作
失败:关系不能改变是因为
中的一个或多个外键属性不可为空。当对
关系进行更改时,相关的外键属性将设置为空值。
如果外键不支持空值,则必须定义新关系
,外键属性必须分配另一个
非空值,否则不相关的对象必须删除。

System.InvalidOperationException occurred 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.

我明白这是因为在集合上的删除只能通过使外键空白来删除关系。我们希望将业务逻辑写入我们的实体,并允许删除。

I understand this is because Remove on the collection only deletes the relationship by nulling the foreign key. We wanted to write our business logic in our entity and allow removal.

因此,从根本上来说,从根本上来说,它是从Represiory(例如OrderRepository中的Order),然后调用实体的一些具体方法。 Order.AddOrderline(Orderline orderline)这将向订单添加一个OrderLine virtual ICollection< OrderLine> OrderLines

So get root entity out out of it's Repostiory e.g Order from OrderRepository then call some specific method of the entity e.g. Order.AddOrderline(Orderline orderline) This adds an OrderLine to the Orders virtual ICollection<OrderLine> OrderLines

但是,我们无法编写代码,如 Order.CancelOrderline(int orderLineId)因为简单地从ICollection中删除导致储蓄变化的错误。

However we can't write code like Order.CancelOrderline(int orderLineId) because simply removing from the ICollection causes an error on savings changes.

通过操纵对象集合,似乎没有办法实现这一点。显然我们可以直接从上下文中删除。不过,我想让它成为实体的一部分。我们可以在Entity Framework的SaveChanges事件上清理没有外键的某些实体吗?显然需要告诉EF什么实体可以被删除,如果它们有空的外键。

There doesn't seem to be anyway to achieve this by just manipulating the object collections. Obviously we can remove directly from Context. However I'd like to make it part of the entity. Can we clean up certain entities with no foreign key on SaveChanges event of Entity Framework? Obviously need to tell EF what entities can be removed if they have null foreign key.

我们目前正在使用一个存储库模式,所以控制器无法访问上下文。显然可以在Order存储库中使用OrderLine存储库或删除OrderLine方法。然而,只是想知道是否可以在实体上编写代码,而不引用持久性机制。

We presently are using a repository pattern so the controller doesn't have access to the context. I could obviously use an OrderLine repository or a remove OrderLine method on the Order repository. However just wondering if it was possible to write the code on the entity without references to the persistence mechanism.

想法?我们要这样做都错了吗?其他ORM允许您从子集合中删除?

Thoughts? Are we going about this all wrong? Do other ORMs allow you to just remove from Child Collections?

推荐答案

我不知道以下是否是一个解决方案,但实体框架支持识别关系。在这种关系中,子实体(依赖)与父(principal)的外键必须是子实体的(复合)主键的一部分。例如 - 使用 DbContext 数据注释 - 您的模型类必须如下所示:

I don't know if the following is a solution for you but Entity Framework supports Identifying Relationships. In such a relationship the foreign key of the child entity (dependent) to the parent (principal) must be part of the (composite) primary key of the child entity. For example - with DbContext data annotations - your model classes have to look like this:

public class Order
{
    [Key]
    public int OrderId { get; set; }

    public ICollection<OrderLine> OrderLines { get; set; }
}

public class OrderLine
{
    [Key, ForeignKey("Order"), Column(Order = 1)]
    public int OrderId { get; set; }

    [Key, Column(Order = 2)]
    public int OrderLineId { get; set; }

    public Order Order { get; set; }
}

您可以使 OrderLineId 如果你想要一个自动生成的身份。重要的只是FK到订单是PK的一部分。

You can make the OrderLineId an autogenerated identity if you want. Important is only that the FK to Order is part of the PK.

这样的代码例如..

using (var ctx = new MyContext())
{
    var order = ctx.Orders.Include("OrderLines").Single(o => o.OrderId == 1);
    var orderLineToDelete = order.OrderLines
        .FirstOrDefault(ol => ol.OrderLineId == 5);
    if (orderLineToDelete != null)
        order.OrderLines.Remove(orderLineToDelete);

    ctx.SaveChanges();
}

...确实删除 orderLineToDelete 从数据库。

...would indeed delete the orderLineToDelete from the database.

更多详细信息是这里识别和不识别关系的注意事项

这篇关于是否可以从收集中删除小孩并解决SaveChanges上的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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