在没有第三方orm框架(如automapper/nhibernate/ef)的情况下,我对通过纯ado.net解决方案处理业务对象中的嵌套集合感到困惑。
请考虑以下情况:
//SalesOrder
public class SalesOrder
{
ICollection<IOrderItem> OrderLines { get; set; }
}
如果我们通过存储库对象从数据库中检索SalesOrder实体,如下所示,
//Retrieve entity via repository object
ISalesOrderRepository repo = new SalesOrderRepository(DbContext);
ISalesOrder order1 = repo.GetOrderByCustomerPo("TN-2202-01");
我们可以使用SQL语句从数据库中查询数据,并将数据填充到SalesOrder实体的相应属性中。
但是如何初始化order1.orderlines的嵌套集合对象呢?
我认为有一种方法可以通过代理模式构建order1.orderlines,如下所示:
public ICollection<IOrderItem> OrderItems
{
get
{
if(_orderItems == null)
{
IOrderItemLazyLoadingProxy lzProxy = new OrderItemLazyLoadingProxy(this);
_orderItems = lzProxy.Load();
return _orderItems;
}
}
}
我对域对象直接与代理对象耦合或依赖于代理对象的上述实现感到困惑。
所以我想知道是否有方法可以处理聚合根对象中的嵌套集合透明性?
谢谢。
最佳答案
您的域对象应该具有持久性无知。他们不应该直接关注持久性问题,但你仍然应该务实。
存储库负责加载整个聚合,因此您的SalesOrderRepository
也应该加载这些项。你可以这样说:
public class SalesOrder
{
private readonly List<SalesOrderItem> _items = new List<SalesOrderItem>();
public IEnumerable<SalesOrderItem> Items
{
get { return new ReadOnlyCollection<SalesOrderItem>(_items); }
}
public void AddItem(string product, decimal price)
{
OnAddItem(new SalesOrderItem(product, price));
}
public void OnAddItem(SalesOrderItem item)
{
_items.Add(item);
}
}
存储库将获取项目日期并实例化它们。
OnAddItem
用于历史数据,仅用于填充内部列表,而AddItem
是一个实际的域命令,指示发生了新的事情。只是一些想法:)