EF代码优先:如何在跟踪DDD时从实体的Collection中删除一行?

hig*_*ace 17 c# domain-driven-design entity-framework code-first

所以这是场景:

DDD声明您使用存储库来获取聚合根,然后使用它来添加/删除它拥有的任何集合.

添加很简单,你简单的调用.Add(Item item)Collection要添加到.保存时,会在数据库中添加一个新行.但是,删除是不同的 - 调用.Remove(Item item)不会从数据库中删除该项,它只是删除外键.所以,虽然,是的,它在技术上不再是集合的一部分,它仍然在数据库中.

阅读,唯一的解决方案是使用数据上下文删除它.但根据DDD,域对象不应该知道数据上下文,因此删除必须在域外进行.

什么是正确的方法?或者让数据库中的孤儿都可以接受(也许是运行例程来清除它们)?

Ste*_*kes 12

我已经通过使用域事件在我正在处理的应用程序中解决了这个问题; 一个DDD概念埃里克埃文斯说应该在他的书中.

虽然不允许域对象知道对象上下文,但是IDomainEventHandler我有一个DomainObjectDeletionHandler从控件返回到我的应用程序层并保存更改之前从对象上下文中删除'已删除'对象的对象.

有关更多信息,我写了一篇关于我的域事件实现以及我如何将所有内容连接在一起的博客.

希望有帮助:)

编辑

例如,如果您有一个Order具有OrderItems类型集合的类OrderItem:

public class Order
{
    // Other stuff

    public void RemoveOrderItem(int orderItemId)
    {
        var orderItemToRemove = OrderItems.First(oi => oi.Id == orderItemId)

        OrderItems.Remove(orderItemToRemove);

        DomainEvents.Raise(new OrderItemRemoved(orderItemToRemove));
    }
}
Run Code Online (Sandbox Code Playgroud)


Jor*_*lli 5

从集合中删除子实体时,EF会将其保留为孤儿,只删除外键.

如果您不想使用DbContext显式删除它,您可以使用所谓的"识别关系"(http://msdn.microsoft.com/en-us/library/ee373856.aspx底部).

诀窍是在子项上设置复合主键,包括父键的主键.

一旦你这样做,当从父集合中删除实体时,它也将从表中删除.