代码之家  ›  专栏  ›  技术社区  ›  penderi

使用ActiveRecord在nHibernate中预先加载延迟加载的实体

  •  4
  • penderi  · 技术社区  · 16 年前

    我正在开发一个项目,这个项目有一个包含各种集合根的富对象模型。

    我们正在使用 城堡 堆叠(单轨通过ActiveRecord连接到NHibernate)。

    我们已将聚合根标记为懒惰 [ActiveRecord(Lazy = true)] 并在我们的存储库中定制了“热切”的例程,以便热切地获取对象图。我们使用hql来定义从根的子集合中获取的渴望,

    例如如果 Account 聚合根(标记为lazy loaded)是我们将要获取的吗? Account .. Order .. Product 完整图形的实体。

    所以到目前为止没有什么意外(希望如此)。

    现在,如果在上面的示例中,产品也被标记 [活动记录(lazy=true)] ,这似乎停止了hql中的热切fetch指令。

    有没有人知道一种方法来强制获取一个懒惰加载的子对象 ??

    干杯 伊恩

    更新 :

    好的,下面是一些示例hql,使用下面“me.yahoo.com/../1”中的示例,我们在获取多对多关系时使用imuliQuery重新爱上n+1依赖项。我们还显式地使用多对多映射类。因此,我们的HQL是:

    from Account a 'm eager loading the graph
    inner join fetch a.AccountsOrders ao 
    inner join fetch ao.Order
    from Account a 'm eager loading the graph
    inner join fetch a.AccountAddresses aa
    inner join fetch aa.Address ad
    where a.ID = ?
    

    …因此,这将执行2个SQL语句并返回所需的最小行集,我们可以将其解析为单个对象图。很好。

    但是…如果说 Address 被标记为“lazy loaded”(和 Order 没有),正在访问 秩序 不触发其他SQL语句,但访问 地址 是的,尽管事实上两者都是迫不及待的。

    那么为什么这个懒惰加载的实体 地址 在上面,是不是很期待上面的陈述?

    3 回复  |  直到 15 年前
        1
  •  0
  •   Gareth Farrington    15 年前

    你为什么想要这种渴望的行为?

    ActiveRecord中的所有关系属性都有一个'lazy='参数,告诉ActiveRecord延迟加载相关对象。除了贝朗斯托。belongsto检查依赖对象的activeRecord属性中lazy=true,然后为该对象创建代理,而不是执行select或join。

    要使延迟加载工作,需要将类实例的所有方法和属性标记为虚拟。这允许ActiveRecord构造动态代理类。

    现在,获取完整的性能图听起来似乎是个好主意,但实际上可能较慢。我有三个很好的理由:

    1.)belongsto有一个fetch选项来定义如何提取相关对象。join强制ar使用join。羊蹄甲选择强制ar为每个对象使用单独的select语句。连接速度很慢,我们看到从切换到单个选择的性能提高了10倍。客户机代码中lazy=true+fetchenum.select和eager之间没有有效的区别。

    2.)nhibernate执行缓存。如果对象已经缓存在会话或2级缓存中,则可以从会话或2级缓存中加载它,并避免额外的工作。

    3.)如果没有引用对象图的一部分,您可能会错过延迟加载的任何好处。再说一次,你会做比需要更多的工作。

        2
  •  1
  •   user47393    16 年前

    对account.order.product实体执行“内部联接获取”。因此,不要像这样(这可能是你已经拥有的):

    "from Account a inner join fetch a.Order where a.ID = ?"
    

    告诉它去拿订单。还有产品:

    "from Account a inner join fetch a.Order inner join fetch a.Order.Product where a.ID = ?"
    
        3
  •  0
  •   Pascal Lindelauf    15 年前

    摘自第225页的“NHiberinate in action”。

    NHibernate目前限制你只获取一个集合热切。

    这可能解释了获取地址的第二个查询。