4

我正在研究一个具有丰富对象模型和各种聚合根集合的项目。使用ActiveRecord在nHibernate中加载惰性加载实体

我们使用城堡堆栈(单轨到nHibernate with ActiveRecord)。

我们已经将聚合根标记为惰性[ActiveRecord(Lazy = true)],并在我们的Repository上定制了“渴望”例程,以便快速获取对象图。我们使用HQL来定义来自我们的根子集合的渴望提取,例如

如果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渴望被上述语句提取?

+0

请发布您的hql – 2008-12-19 15:37:01

+0

它是通过nHibernate升级解决的。 – penderi 2010-07-27 08:18:26

回答

0

你为什么想急切的行为吗?

ActiveRecord中的所有关系属性都有一个'Lazy ='参数来告诉ActiveRecord延迟加载相关对象。除BelongsTo以外的所有内容。 BelongsTo检查依赖对象的ActiveRecord属性是否具有Lazy = true,然后为对象创建代理而不是执行选择或连接。

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

现在听起来像是一个好主意,可以获取完整的性能图表,但实际上它可能会更慢。我有3个很好的理由:

1.)BelongsTo有一个Fetch选项来定义如何拉取相关的对象。 FetchEnum.Join强制AR使用Join。 FetchEnum。选择强制AR为每个对象使用单独的选择语句。联接速度缓慢,我们看到从切换到单个选择后性能提高了10倍。 Lazy = true + FetchEnum.Select和eager之间的客户端代码没有任何效果差异。

2.)NHibernate做缓存。如果对象已被缓存在会话中或二级缓存中,则可以在该对象中加载该对象并避免额外的工作。 3.如果没有引用对象图的一部分,你会错过延迟加载的好处。再次,你会做更多的工作,而不是必要的。

1

在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 = ?" 
+2

这是为什么被拒绝?在需要急切加载的情况下,这不是一个好的解决方案吗?从-3投票到-2。 – Andy 2011-12-09 20:04:20

0

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

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

这可能会解释第二个查询地址。