我正在尝试使用HQL对一个简单的查询进行分页,并检索总行数作为同一查询的一部分。
我的查询很简单......
var members = UnitOfWork.CurrentSession.CreateQuery(@"
select m
from ListMember as m
join fetch m.Individual as i")
.SetFirstResult(pageIndex*pageSize)
.SetMaxResults(pageSize)
.List<ListMember>();
在ListMember类中,Individual被映射为多对一。这非常有效。分页按预期工作并生成以下Sql ...
SELECT TOP ( 10 /* @p0 */ ) DirPeerG1_1_0_,
Director1_0_1_,
Director2_1_0_,
Forename2_0_1_,
Surname0_1_
FROM (SELECT listmember0_.DirPeerGrpMemberID as DirPeerG1_1_0_,
listmember1_.DirectorKeyID as Director1_0_1_,
listmember0_.DirectorKeyId as Director2_1_0_,
listmember1_.Forename1 as Forename2_0_1_,
listmember1_.Surname as Surname0_1_,
ROW_NUMBER()
OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row
FROM tblMembers listmember0_
inner join tblIndividuals listmember1_
on listmember0_.DirectorKeyId = listmember1_.DirectorKeyID) as query
WHERE query.__hibernate_sort_row > 10 /* @p1 */
ORDER BY query.__hibernate_sort_row
我读过Ayende发布的这篇文章Paged data + Count(*) with NHibernate: The really easy way!,所以我试着在我的查询中实现它。
我按照文章中的步骤添加了名为rowcount()
的自定义HQL函数,并将我的查询更改为此...
var members = UnitOfWork.CurrentSession.CreateQuery(@"
select m, rowcount()
from ListMember as m
join fetch m.Individual as i")
.SetFirstResult(pageIndex*pageSize)
.SetMaxResults(pageSize)
.List<ListMember>();
生成的Sql几乎是正确的,但它包含两次列之一导致此错误...
System.Data.SqlClient.SqlException: 列'''已指定 “查询”多次。
它生成的Sql看起来像这样......
SELECT TOP ( 10 /* @p0 */ )
col_0_0_,
col_1_0_,
Director1_0_1_,
DirPeerG1_1_0_,
Director1_0_1_,
Director2_1_0_,
Forename2_0_1_,
Surname0_1_
FROM (SELECT
listmember0_.DirPeerGrpMemberID as col_0_0_,
count(*) over() as col_1_0_,
listmember1_.DirectorKeyID as Director1_0_1_,
listmember0_.DirPeerGrpMemberID as DirPeerG1_1_0_,
listmember1_.DirectorKeyID as Director1_0_1_,
listmember0_.DirectorKeyId as Director2_1_0_,
listmember1_.Forename1 as Forename2_0_1_,
listmember1_.Surname as Surname0_1_,
ROW_NUMBER()
OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row
FROM RCMUser.dbo.tblDirPeerGrpMembers listmember0_
inner join RCMAlpha.dbo.tblDirectorProfileDetails listmember1_
on listmember0_.DirectorKeyId = listmember1_.DirectorKeyID) as query
WHERE query.__hibernate_sort_row > 10 /* @p1 */
ORDER BY query.__hibernate_sort_row
由于某种原因,它在投影中包含Director1_0_1_
列两次,这会导致此错误。这个Sql令人沮丧地接近我想要的,我希望NHibernate专家可以帮助解释为什么会发生这种情况。
感谢@Jason的建议。我尝试使用非泛型版本的.List()方法执行查询,但遗憾的是,这也产生了与重复列相同的Sql ......
var members = UnitOfWork.CurrentSession.CreateQuery(@"
select m, rowcount()
from ListMember as m
join fetch m.Individual as i")
.SetFirstResult(pageIndex * pageSize)
.SetMaxResults(pageSize)
.List()
.Cast<Tuple<ListMember, int>>()
.Select(x => x.First);
如果没有进入NH源代码,这似乎不可能。我的解决方案要求已经改变,我不再追求答案了。
总之,解决方案是......
答案 0 :(得分:1)
嗯,有一个问题是你正在使用ListMember类型的List方法。在您链接的页面的示例中,他使用List()返回元组列表。元组的第一项是ListMember,第二项是行计数。该列表&lt;&gt;可能会影响您的查询,即使它确实返回也可能抛出异常。
尝试使用:
var tuples = UnitOfWork.CurrentSession.CreateQuery(@"
select m, rowcount()
from ListMember as m
join fetch m.Individual as i")
.SetFirstResult(pageIndex*pageSize)
.SetMaxResults(pageSize)
.List();
var members = tuples.Select<Tuple<ListMember, int>, ListMember>(x => x.Item1);
但我有点同意@dotjoe。 MultiQuery可能更容易。这就是我使用的。这是一个很好的link来自你之前链接的同一作者(Ayende)。