2010-08-03 45 views
8

我試圖加載所有的收藏品,使用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團隊的人可能會對此有所瞭解? 謝謝

回答

3

你缺少的一件事就是你應該使用FetchMany()而ThenFetchMany()是子屬性是一個集合。

7

顯然,在這種情況下沒有「正確」的方式來使用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

0

正如此外,Leora說,取孩子集合時確保你用

FetchMany() 

ThenFetchMany() 

新的Fetch應該從根開始,但這並不總是會發生。有時您需要將它們創建爲單獨的查詢或使用Criteria Futures來批量提取多個提取。

0
 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); 
//... 
相關問題