在使用ActiveRecord NHibernate的懒加载实体的预先加载
-
22-08-2019 - |
题
我的工作是与各组总根的丰富的对象模型的项目。
我们正在使用的城堡强>栈(单轨通过到的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的限制你急切地获取只有一个集合。
这或许可以解释所述第二查询用于读取的地址。