使用 GroupBy 的 NHibernate LINQ 查询

NHibernate LINQ query with GroupBy

我正在努力将 SQL 转换为 NHibernate HQL。

SQL 查询

SELECT Posts.id, Count(Comments.id) FROM Posts LEFT JOIN Comments ON Posts.id=Comments.fk_post GROUP BY Posts.id

LINQ

Session.Query<Post>().Fetch(x => x.Comments).GroupBy(x => x.id, x => x.Comments)
                .Select(x => new { PostId = x.Key, CommentCount = x.Single().Count }).ToList();

这仍然失败,但出现异常: 参数 'inputInfo' 的类型为 'Remotion.Linq.Clauses.StreamedData.StreamedSingleValueInfo',而预期的类型为 'Remotion.Linq.Clauses.StreamedData.StreamedSequenceInfo'。

我的查询有什么问题?

试试这个查询:

var query = 
    from p in Session.Query<Post>()
    from c in p.Comments.DefaultIfEmpty()
    group c by p.Id into g
    select new 
    {
        PostId = g.Key,
        CommentCount = g.Sum(x => (int?)c.Id == null ? 0 : 1)
    }

var result = query.ToList();;

所以你有 PostsComments 的表格。 Post和Comments是一对多的关系:每个Post有0个或多个Comments,每个Comment正好属于一个Post,即Post外键 Comments.fk_post 指的是。

您想获取每个 Post 的 ID,以及此 Post 的评论数。

每当您需要 select“具有零个或多个子项的项目”时,例如学校及其学生、客户及其订单,或者在您的情况下 Post 及其评论, 考虑使用 Queryable.GroupJoin.

的重载之一

如果您看到 SQL Left Outer Join 后跟 GroupBy,您还可以看到 GroupJoin 是最明显的解决方案。 每当您看到 SQL left outer join 后跟 GroupBy 时,几乎可以肯定您需要 GroupJoin。

如果您想要的不仅仅是“项目及其子项目”,请使用具有参数 resultSelector 的重载。

我不知道 nHibernate,我假设 SessionQueryFetch 用于获取 IQueryable。由于这不是问题的一部分,我将由您来获取 IQueryables:

IQueryable<Post> posts = ...
IQueryable<Comment> comments = ...

// GroupJoin Posts with Comments
var postIdsWithCommentsCount = posts.GroupJoin(comments,

post => post.Id,               // from every Post take the primary key
comment => comment.fk_post,    // from every Comment take the foreign key to Post

// parameter resultSelector: from every Post, with all its zero or more Comments,
// make one new
(post, commentsOfThisPost) => new
{
    Id = post.Id,
    Count = commentsOfThisPost.Count(),
});