这是使用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 syntaxFetch

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 
+0

+1,不敢相信这实际上有效。谢谢。 – 2013-04-09 17:54:54

正如此外,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); 
//...