哪一层负责为实体的子对象实现LazyLoading策略 [英] What layer is responsible for implementing a LazyLoading strategy for children objects of an entity

查看:76
本文介绍了哪一层负责为实体的子对象实现LazyLoading策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个订单作为汇总根。订单包含一个或多个订单项

Let's say you have an order as an aggregate root. An order contains one or more line items.

据我了解,在系统询问时实例化订单对象是存储库的责任。

It is my understanding that it's the repository's responsibility to instantiate an order object when asked.

可以在创建订单对象时加载订单项(热切加载),也可以在客户代码访问订单项集合时填充订单项集合(延迟加载)。

The line items can be loaded at the time of the order object's creation (eager loaded), or the line item collection can be populated when it is accessed by the client code (lazy loaded).

如果我们使用紧急加载,则似乎在创建订单时,存储库代码将负责对订单项进行补水。

If we are using eager loading, it's seems that the repository code would take responsibility with hydrating the line items when the order is created.

但是,如果我们使用延迟加载,那么在访问LineItems集合而不在订单域类上不依赖存储库的情况下如何调用存储库?

However if we are using lazy loading, how is the repository called when the LineItems collection is accessed without creating a dependency on the repository from the order domain class?

推荐答案

主要问题在于存储库能够获得仅汇总根(表示汇总),因此您不能使用存储库来获取订单项。

Main problem is in Repository's ability to get only aggregate roots (presenting aggregates), thus you cannot use Repository to get line items. This can lead to aggregate encapsulation violation.

我提出类似的建议:

//Domain level:

public interface IOrderItemList {

   IEnumerable<OrderItem> GetItems();

}

public class Order {

    private IOrderItemList _orderItems;

    public IEnumerable<OrderItem> OrderItems 
          { get { return _orderItems.GetItems() } };

    public Order(IOrderItemList orderItems) 
    {
        _orderItems = orderItems;
    }
}

public class OrderItemList : IOrderItemList
{
    private IList<OrderItem> _orderItems;

    public IEnumerable<OrderItem> GetItems() {
        return _orderItems; //or another logic
    }

    //other implementation details
}

//Data level

public class OrderItemListProxy : IOrderItemList
{
    //link to 'real' object
    private OrderItemList _orderItemList;

    private int _orderId;
    //alternatively:
    //private OrderEntity _orderEntity;

    //ORM context
    private DbContext _context;

    public OrderItemListProxy(int orderId, DbContext context)
    {
       _orderId = orderId;
       _context = context;
    }

    public IEnumerable<OrderItem> GetItems() {
        if (_orderItemList == null) 
        {
            var orderItemEntities = DbContext.Orders
              .Single(order => order.Id == _orderId).OrderItems;

            var orderItems = orderItemEntites.Select(...);
            //alternatively: use factory to create OrderItem from OrderItemEntity
            _orderItemList = new OrderItemList(orderItems);
        }
        return _orderItemList.GetItems();
    }

}

public class OrderRepository
{
   //ORM context
   private DbContext _context;

    Order GetOrder(int id)
    {
        var orderEntity = _context.Single(order => order.Id == id);
        var order = new Order(new OrderItemListProxy(id, _context))
        //alternatively:
        //var order = new Order(new OrderItemListProxy(orderEntity, _context))
        ...
        //init other fields
        ...
    }
    //other methods
    ...
}

最重要的是 IOrderItemList 对应于域层,但是 OrderItemListProxy 对应于数据层。

Most important here is that IOrderItemList corresponds to domain layer, but OrderItemListProxy corresponds to data layer.

最后,


  1. 您可以使用 IList< OrderItem> 代替自定义的 IOrderItemList 或其他合适的界面。

  2. 代理实现可能有所不同。

  3. 我没有提供使用数据库上下文的最佳实践,这可能取决于您使用的技术。

  1. You may use IList<OrderItem> instead of custom IOrderItemList or another appropriate interface.
  2. Proxy implementation may differ.
  3. I don't provide best practicies for using db context, it may depend on technologies you use.

这篇关于哪一层负责为实体的子对象实现LazyLoading策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆