我正在尝试使用NHibernate 3 alpha 1热切地加载所有集合。我想知道这是否正确使用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团队的人可以对此有所了解? 感谢
答案 0 :(得分:10)
显然,在这种情况下,没有“正确”的方式来使用ThenFetch
。您的示例工作正常,但生成的SQL包含许多Milestone
的连接,这不是正确的。
使用IQueryOver
代替IQueryable
,您可以在Fetch
中使用complex syntax:
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
答案 1 :(得分:3)
你缺少的一件事是你应该使用FetchMany()而ThenFetchMany()是子属性是一个集合。
答案 2 :(得分:1)
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);
//...
答案 3 :(得分:0)
正如leora所说,确保在获取您使用的儿童收藏品时
FetchMany()
ThenFetchMany()
新的Fetch应该从root中获取,但这并不总是会发生。有时您需要将它们创建为单独的查询,或使用Criteria Futures批量处理多次获取。