2011-05-12 174 views
3

我使用NHibernate與QueryOver API來查詢我的域實體。問題是獲得重複的結果。例如查詢以下域時: domainNHibernate實體投影

我使用如下代碼:

var list = Session.QueryOver<Post>() 
        .JoinQueryOver<Comment>(x => x.Comments) 
        .Where(c => c.Name == "Name") 
        .Take(5) 
        .List(); 

生成的SQL就會像下面:

SELECT Top(5) * FROM Posts p left outer join Comments c on p.Id = c.PostId 

這裏的問題是,左連接完成後產生記錄集有多於5行。然後TOP函數應用並削減結果。例如,如果第一篇文章有​​5條評論,我會得到這篇文章5次,不會得到其他人。

我知道它爲什麼會發生,並發現一個不錯的post。 但有沒有一個投影會告訴nhibernate從Post實體中只選擇列,而不是在select中添加來自Comment實體的列?也許應該使用其他方法(不是JoinQueryOver)?

回答

3

首先,您需要從Comment to Post回來參考。我假設它被稱爲「Post」。

然後使用子查詢來過濾註釋和後續的帖子。

//the alias for post 
Post post = null; 

var list = Session.QueryOver(() => post) 
      .WithSubquery.WhereProperty(() => post.Id) 
       .In(NHibernate.Criterion.QueryOver.Of<Comment>() 
        .Where(c => c.Name == "Name") 
        .Select(c => c.Post.Id)) 
      .Take(5) 
      .List(); 

生成的SQL應該是在這樣的人:

SELECT Top(5) * FROM Posts p where p.Id in (select PostID from Comments c where c.Name = 'Name') 
+0

是的,在我的應用程序中,我以子查詢結束了。是否有隻從一張桌子上得到結果的錯誤? – Sly 2011-05-12 11:09:48

+0

我不明白你的問題。我寫的例子只返回一個表格,即「Posts」的結果。內部選擇只對名稱爲「名稱」的評論進行過濾 – psousa 2011-05-12 12:54:07

+0

我想要類似於選擇不同的帖子。*來自帖子p內部加入評論c – Sly 2011-05-12 13:06:32

-2

我們已經使用了criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());以避免重複記錄。

+0

這裏不行。 DB沒有返回所有行,只是第一個5 – Sly 2011-05-12 07:01:15

+0

爲什麼不映射到ISet呢? – csano 2011-05-12 17:33:16

0

如果你想避免在加入則可以使用變壓器DistinctRootEntityResultTransformer的結果重複該變壓器將從中刪除重複但如果他們與另一個實體連接在一起,它不會刪除評論中的重複內容。在這種情況下,您將不得不開發自己的變壓器以消除第二層次上的重複。