我的工作是与各组总根的丰富的对象模型的项目。

我们正在使用的城堡栈(单轨通过到的nHibernate用ActiveRecord)。

我们已经标记聚集根懒惰[ActiveRecord(Lazy = true)]和已经定制“急切”例程在我们的库到预先抓取一个对象图。我们使用HQL从我们的我们的根的子集,

定义急于取

e.g。如果Account是聚合根(和标记延迟加载),用于一个完全图,我们将预先抓取Account .. Order .. Product实体。

因此,没有意外,迄今(希望)。

现在,如果在上述示例中,产品也被标记[ActiveRecord(Lazy = true)],这似乎停止在HQL急切取指令。

有谁知道一个办法迫使急于获取延迟加载子对象的

干杯 伊恩

<强>更新

确定这里是一些例子HQL,从“me.yahoo.com/../1”使用下面的例子中,我们使用IMuliQuery许多一对多的关系,在获取时,reslove 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被标记为延迟加载(和Order不是),访问Order不会触发进一步的SQL语句,但访问Address确实,尽管双方都渴望加载。

那么,为什么不是延迟加载实体Address,上面,渴望获取由上述声明?

有帮助吗?

解决方案

为什么要急切的行为?

在ActiveRecord的所有关系的属性有一个“懒惰=”参数告诉ActiveRecord的懒惰负载相关对象。所有除属于关联。属于关联检查从属对象具有懒惰=在其ActiveRecord的属性真,然后创建该对象的代理而不是做一个选择的或加入。

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

现在这听起来是个好主意,以获取完整的图形性能,但在实践中它可能更慢。我有3个很好的理由:

1。)属于关联有一个抓取选项来定义对象如何相关的拉动。 FetchEnum.Join力量AR使用加入。 FetchEnum。选择势力AR用于每个对象单独的select语句。连接是缓慢的,我们看到切换到个人选择10倍的性能提升。有在懒惰=真+ FetchEnum.Select和渴望之间的客户端代码没有有效的差异。

2)的NHibernate确实缓存。如果对象是在会话或在2级缓存已经缓存它可以在那里加载形式,避免了额外的工作。

3。)你会错过的情况下延迟加载的任何好处,你没有引用的对象图的一部分。同样,你会做的比需要更多的工作。

其他提示

做一个“内部联接提取”关于Account.Order.Product实体。因此,而不是像这样(这是很可能已经):

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

给它来获取Order.Product以及:

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

从 “NHibernate的在行动”,225页:

  

目前NHibernate的限制你急切地获取只有一个集合。

这或许可以解释所述第二查询用于读取的地址。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top