3

我有两个简单的课程

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

并得到

标题评论
博客 1 0
博客 2 0
博客 3 0
博客 4 4
博客 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获得整个解决方案。

干杯

B.

4

1 回答 1

1

Why do you always find the answer just after you've posted the question?

The answer was the JoinAlias method, with an alias placeholder:

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]
               });

This does exactly as I expected it to.

B.

于 2012-08-29T12:44:06.977 回答