这是使用ThenFetch()加载多个集合的正确方法吗?
问题描述:
我试图加载所有的收藏品,使用NHibernate 3 alpha 1。我想知道这是否使用ThenFetch()的正确方法?这是使用ThenFetch()加载多个集合的正确方法吗?
具有复数名称的属性是集合。其他人只是一个单一的对象。
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi).Fetch(mi => mi.Milestone)
.ThenFetch(m => m.PrimaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.SecondaryOwners)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Predecessors)
.Fetch(mi => mi.Milestone)
.ThenFetch(m => m.Function)
.Fetch(mi => mi.Milestone)
.ThenFetchMany(m => m.Jobs)
.ThenFetch(j => j.Source)
;
我想提出这个在NHibernate forums可惜访问谷歌组从我所在的地方被禁止的。我知道Fabio就在这里,所以NHibernate团队的人可能会对此有所了解? 谢谢
答
你缺少的一件事就是你应该使用FetchMany()而ThenFetchMany()是子属性是一个集合。
答
显然,在这种情况下没有“正确”的方式来使用ThenFetch
。你的例子工作正常,但生成的SQL包含很多连接到Milestone
,这是不对的。
使用IQueryOver
代替IQueryable
允许你使用complex syntax在Fetch
:
Fetch(p => p.B)
Fetch(p => p.B.C) // if B is not a collection ... or
Fetch(p => p.B[0].C) // if B is a collection ... or
Fetch(p => p.B.First().C) // if B is an IEnumerable (using .First() extension method)
所以你的情况这将是:
query // = session.QueryOver<X>()
.Fetch(mi => mi.Milestone).Eager
.Fetch(mi => mi.Milestone.PrimaryOwners).Eager
.Fetch(mi => mi.Milestone.SecondaryOwners).Eager
.Fetch(mi => mi.Milestone.Predecessors).Eager
.Fetch(mi => mi.Milestone.Function).Eager
.Fetch(mi => mi.Milestone.Jobs).Eager
.Fetch(mi => mi.Milestone.Jobs.First().Source).Eager
答
正如此外,Leora说,取孩子集合时确保你用
FetchMany()
ThenFetchMany()
新的Fetch应该从根开始,但这并不总是会发生。有时您需要将它们创建为单独的查询或使用Criteria Futures来批量提取多个提取。
答
IQueryable<T> milestoneInstances = Db.Find<T, IQueryable<T>>(db =>
from mi in db
where mi.RunDate == runDate
select mi);
var fetch = milestoneInstances.Fetch(f => f.Milestone);
fetch.ThenFetch(f => f.PrimaryOwners);
fetch.ThenFetch(f => f.SecondaryOwners);
//...
+1,不敢相信这实际上有效。谢谢。 – 2013-04-09 17:54:54