我有一个带有添加,更新,删除的通用存储库。
我们将其命名为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;