我正在努力将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.林q.Claunces.StreamedData_StreamedSequenceInfo">
我的查询出了什么问题?
所以您有Posts
和Comments
的表。帖子和评论之间存在一对多的关系:每个帖子都有零个或多个评论,每个评论都只属于一个帖子,即外键Comments.fk_post
所指的帖子
您需要获取每个帖子的Id,以及此帖子的评论数。
每当你需要选择";具有零个或多个子项目的项目";,像学校和他们的学生,客户和他们的订单,或者在你的情况下发布他们的评论,考虑使用Queryable.GroupJoin.的重载之一
您还可以看到,如果您看到SQL左外部联接后面跟着GroupBy,那么GroupJoin是最明显的解决方案。每当您看到SQL左外部联接后面跟着GroupBy时,几乎可以肯定您需要GroupJoin。
如果你想要的不是juse";项目及其子项目";,使用具有参数resultSelector的重载。
我不知道nHibernate,我假设Session
、Query
、Fetch
用于获取IQueryables。由于这不是问题的一部分,我让你来获得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(),
});
尝试此查询:
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();;