2011-05-12 80 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的结果重复该变压器将从中删除重复但如果他们与另一个实体连接在一起,它不会删除评论中的重复内容。在这种情况下,您将不得不开发自己的变压器以消除第二层次上的重复。