2011-10-03 62 views
0

我有一個聚合根,它是一個WallPost。 WallPost可以有零到多個WallPostComments。如何爲每個實體獲取包含所有子項的父實體的前20位

我希望編寫一個查詢來獲取20個牆貼(按DateCreated降序排列),並且還熱切地獲取這20個牆貼的所有評論。

我嘗試過使用NHibernate Linq和Fetch()子句,但是這會導致「使用集合提取指定的firstResult/maxResults;在內存中應用!」錯誤。我試過其他

有兩種方法:

var wallPostQuery = _session.QueryOver<WallPost>() 
      .Where(x => x.WallId == wallId) 
      .OrderBy(x => x.DateCreated) 
      .Desc 
      .Left.JoinQueryOver(x => x.Comments) 
      .Take(20) 
      .Future<WallPost>(); 

但是,意外的驚喜(當然,不是真的)這個帶回每個零或一個評論20個塗鴉牆。我得到了重複的牆貼,這不是我想要的。

一個更好的查詢是

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 

_session.QueryOver<WallPost>().Where(x => x.WallId == wallId).Left.JoinQueryOver(x => x.Comments).Future<WallPost>(); 

var wallPosts = wallPostQuery.ToList(); 

這給了我與他們相關的註釋20個塗鴉牆,但查詢以2種選擇,其中第二選擇加入WallPost到WallPostComment,有效地拉回所有牆執行帖子和評論(僅由WallPostId過濾)。這可以很好地工作,但有很少的帖子 - 但我無法想象這個縮放非常好。

必須有更好的方法 - 但我似乎無法弄清楚。有什麼建議麼?

回答

1

我認爲我發現的solution類似(更復雜一點)的問題可能會對您有所幫助。
東西沿着線:

var wallPostIdsQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>() 
.Select(p => p.Id); 

var wallPostsQuery = _session.QueryOver<WallPost>().WithSubquery.WhereProperty(p => p.Id).In(wallPostIdsQuery); 

var commentsQuery = _session.QueryOver<WallPostComment>().WithSubquery.WhereProperty(p => p.WallPostId).In(wallPostIdsQuery); 

if (wallPostsQuery.Count() == 0) 
{ 
    return wallPostsQuery.List(); 
} 

NHibernateUtil.Initialize(wallPostsQuery.First().Comments); 

,或者可能只是這兩個線 -

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 
NHibernateUtil.Initialize(wallPostQuery.First().Comments); 

,重要的是要記住的意見收集與「再選擇」抓取策略映射。

+0

感謝您的幫助。這工作(我用你的建議較短的版本),雖然NHibernate的Profiler抱怨SELECT N + 1(因爲NHibernateUtil.Initialize做了10次後續選擇),我比這更喜歡我自己的解決方案。現在 - 我注意到,用於獲取註釋的SELECT語句一次獲取兩個帖子的這些語句:WHERE comments0_.WallPost_id(193,192)。有沒有辦法一次抓取它們? –

+0

這看起來很奇怪;是使用子選擇策略映射的評論集合? –

+0

嗯...不,我得到的是這個:var wallPostQuery = _session.QueryOver ().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc。拿(20)。未來(); NHibernateUtil.Initialize(wallPostQuery.First()。Comments); –

相關問題