从聚合根中删除子项

时间:2012-12-13 14:00:45

标签: entity-framework repository domain-driven-design aggregateroot

我有一个共同的存储库,其中添加更新删除。 我们将其命名为 CustomerRepository

我有一个名为客户的实体(POCO),它是一个聚合根,地址

public class Customer
{
     public Address Addresses { get; set; }
}

我处于一个独立的实体框架5场景中。

现在,让我们说在获得客户后,我选择删除客户地址。 我通过更新方法将客户聚合根提交到存储库。

如何保存对地址所做的修改?

  1. 如果地址id为0,我可以认为该地址是新的。
  2. 对于地址的其余部分,我可以选择附加所有地址,并将其标记为已更新,无论如何。
  3. 对于已删除的地址,我看不到解决方法......
  4. 我们可以说这个解决方案不完整且效率低下。

    那么应该如何更新聚合根子项呢?

    我是否必须使用 AddAddress UpdateAddress DeleteAddress 等方法完成 CustomerRepository

    虽然它似乎有点打破了这种模式......

    我是否在每个POCO上都设置了持久性状态:

    public enum PersistanceState
    {
         Unchanged,
         New,
         Updated,
         Deleted
    }
    

    然后我的 CustomerRepository 只有一种方法,保存

    在这种情况下,似乎我正在重新构建实体“非POCO”对象,并将数据访问相关属性添加到业务对象...

2 个答案:

答案 0 :(得分:2)

首先,您应该使用Add,Update和Delete方法保存您的存储库,尽管我个人更喜欢Add,indexer set和Remove,以便存储库看起来像应用程序代码的内存集合。

其次,存储库应负责跟踪持久性状态。我甚至没有使用

混乱我的域对象
object ID { get; }
像某些人一样。相反,我的存储库看起来像这样:

public class ConcreteRepository : List<AggregateRootDataModel>, IAggregateRootRepository

我使用AggregateRootDataModel类来跟踪内存中对象的ID以及跟踪任何持久性信息。在你的情况下,我会把一个属性

List<AddressDataModel> Addresses { get; }

在我的CustomerDataModel类上,该类还包含Customer域对象以及客户的数据库ID。然后,当客户更新时,我会得到如下代码:

public class ConcreteRepository : List<AggregateRootDataModel>, IAggregateRootRepository
{
    public Customer this[int index]
    {
        set
        {
            //Lookup the data model
            AggregateRootDataModel model = (from AggregateRootDataModel dm in this
                                           where dm.Customer == value
                                           select dm).SingleOrDefault();
            //Inside the setter for this property, run your comparison 
            //and mark addresses as needing to be added, updated, or deleted.
            model.Customer = value;
            SaveModel(model); //Run your EF code to save the model back to the database.
        }
    }
}

这种方法的主要警告是您的域模型必须是引用类型,并且您不应该重写GetHashCode()。这样做的主要原因是当您对匹配数据模型执行查找时,哈希代码不能依赖于任何可更改属性的值,因为即使应用程序代码修改了值,它也需要保持不变。域模型实例上的属性。使用此方法,应用程序代码变为:

IAggregateRootRepository rep = new ConcreteRepository([arguments that load the repository from the db]);
Customer customer = rep[0]; //or however you choose to select your Customer.
customer.Addresses = newAddresses;  //change the addresses
rep[0] = customer;

答案 1 :(得分:1)

简单的方法是使用自我跟踪实体What is the purpose of self tracking entities?(我不喜欢它,因为跟踪是不同的责任)。

很难,你拿原始收藏品进行比较: - /

Update relationships when saving changes of EF4 POCO objects

其他方式可能是,事件追踪?