我有一个带有添加,更新,删除的通用存储库。
我们将其命名为CustomerRepository。

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

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


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

现在,假设在获得客户之后,我选择删除客户地址。
我通过Update方法将Customer聚合根提交到存储库。

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


如果地址ID为0,我可以假设该地址是新的。
对于地址的其余部分,我可以选择附加所有地址,无论如何都将其标记为已更新。
对于已删除的地址,我看不到任何解决方法...


我们可以说这种解决方案是不完整且效率低下的。

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

我是否必须使用AddAddress,UpdateAddress,DeleteAddress之类的方法来完成CustomerRepository?

看来这虽然会打破格局...

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

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


然后在我的CustomerRepository中只有一种方法Save?

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

最佳答案

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

其次,存储库应负责跟踪持久性状态。我什至都不会把我的域对象弄乱

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;

10-04 16:57