使用QueryOver / ICriteria在NHibernate中聚合左连接

时间:2012-08-29 11:30:42

标签: c# nhibernate queryover

我有两个简单的类

public class Blog
{
  public Blog(){
    Comments=new List<Comment>();
  }
  public virtual Guid Id { get; set; }
  public virtual string Title { get; set; }
  public virtual string Text { get; set; }
  public virtual DateTime CreatedDate { get; set; }
  public virtual IList<Comment> Comments { get; set; }
}

public class Comment
{
  public virtual Guid Id { get; set; }
  public virtual string Author { get; set; }
  public virtual string Text { get; set; }
}

使用AutoMap进行映射,一切都很棒。我可以添加和保存实体没有问题。

我想要做的是使用QueryOver获取每个博客的评论数量,但包括那些没有评论的博客,所以在SQL中:

SELECT b.Title,COUNT(c.ID) AS Comments
FROM Blogs b LEFT JOIN Comments c ON b.ID=c.BlogID

并获取

Title  Comments
Blog 1 0
Blog 2 0
Blog 3 0
Blog 4 4
Blog 5 0

我最接近的是

var results=session.QueryOver<Blog>()
.Left.JoinQueryOver<Comment>(b=>b.Comments)
.TransformUsing(new DistinctRootEntityResultTransformer())
.List<Blog>()
.Select(b => new {
Id = b.Id,
Title = b.Title,
Comments=b.Comments.Count
});

得到了正确的答案,但SQL运行为

SELECT b.Id,b.Title,c.ID,c.Author,etc... AS Comments
FROM Blogs b LEFT JOIN Comments c ON b.ID=c.BlogID

然后在客户端进行计数,这似乎不是最有效的方法。

可以使用QueryOver或ICriteria完成吗?如果可能,我宁愿不使用hql。

如果您想查看所有配置等,可​​以在https://github.com/oharab/NHibernateQueriesSpike获得整个解决方案。

干杯

1 个答案:

答案 0 :(得分:1)

为什么在发布问题后总能找到答案?

答案是JoinAlias方法,带有别名占位符:

Comment comment=null;
var results=session.QueryOver<Blog>()
    .Left.JoinAlias(b=>b.Comments,()=>comment)
    .SelectList(
        list=>list
        .SelectGroup(b=>b.Id)
        .SelectGroup(b=>b.Title)
        .SelectCount(b=>comment.Id)
    )
    .List<object[]>()
    .Select(b => new {
                Id = (Guid)b[0],
                Title = (string)b[1],
                Comments=(int)b[2]
               });

这完全符合我的预期。