我有帖子,投票和评论表。每个帖子可以有N票和N条评论。我一直试图找到一种方法来使用Nhibernate HQL进行此查询但没有成功。
SELECT P.Id, P.Title, P.TextDescription, ISNULL(V.TotalVotes,0), ISNULL(C.TotalComments, 0)
FROM
Post P
LEFT JOIN
(SELECT
PostId, count(PostId) as TotalVotes
FROM Vote
GROUP BY PostId) V
ON V.PostId = P.Id
LEFT JOIN
(SELECT
PostId, count(PostId) as TotalComments
FROM Comment
GROUP BY PostId) C
ON C.PostId = P.id
我将GROUP BY聚合推送到嵌套的SELECT语句中,因为我想只对PostId进行分组而不是所有其他列。我的域类:
后期属性:
int Id { get; set; }
string Title { get; set; }
string TextDescription { get; set; }
IList<Comment> Comments { get; set; } -> HasMany
IList<Vote> Votes { get; set; } -> HasMany
评论 - 属性:
int Id { get; set; }
Post Post { get; set; } -> reference
投票
int Id { get; set; }
Post Post { get; set; } -> reference
我真的对此感到困惑。我希望我不会走错方向。也许我应该只使用Nhibernate公式属性,我可以为我的计数声明一个任意的SQL表达式。
非常感谢任何帮助..
谢谢!
答案 0 :(得分:2)
对于您要执行的操作,您需要编写任何HQL查询 由于您的类中有集合,并且已将它们映射到.hbm.xml文件中(如果您使用的是流畅的nhibernate,请忽略它)
<bag name="Comments" inverse="true" lazy="extra">
<key column="CommentId" />
<one-to-many class="Comment,mylib" />
</bag>
<bag name="Votes" inverse="true" lazy="extra">
<key column="VoteId" />
<one-to-many class="Vote,mylib" />
</bag>
致电
Post post = ISession.Get<Post>(postId);
使用代理初始化Comments
和Votes
个集合。
当您触摸该集合时
post.Comments.Count
NHibernate将使用PostId postId
在注释上触发选择计数(*)。
如果你绝对想用公式实现这个(因为你希望每次获取帖子时都能看到计数),你就不需要HQL(或那个问题的标准)查询
编辑: 由于您不需要公式并且想要在一次往返中获取结果,因此这里是HQL的解决方案(需要上面的集合映射)
IQuery query = nhSession.CreateQuery("select p, count(p.Comments), p.(p.Votes) from Post p where p.id = :postId");
query.SetInt32("postId", postId);
object result = query.UniqueResult();
其中result是一个数组(我认为是ArrayList),其中result [0]是Post类型对象,result [1]是注释计数(int / long),result [2]是投票计数(int / long) )
答案 1 :(得分:0)
如果使用lazy =“extra”映射集合,则其Count属性不会导致集合的加载。