使用SQL Server进行NHibernate分页
当使用使用SQL Server进行NHibernate分页,nhibernate,sql-server-2000,paging,Nhibernate,Sql Server 2000,Paging,当使用SetFirstResult(start)和SetMaxResults(count)方法来实现分页时,我注意到生成的查询只从一些表中选择top count*,而不考虑start参数,或者至少不在数据库级别。如果我指示NHibernate执行以下查询: var users = session.CreateCriteria<User>() .SetFirstResult(100) .SetMaxResult
SetFirstResult(start)
和SetMaxResults(count)
方法来实现分页时,我注意到生成的查询只从一些表中选择top count*,而不考虑start
参数,或者至少不在数据库级别。如果我指示NHibernate执行以下查询:
var users = session.CreateCriteria<User>()
.SetFirstResult(100)
.SetMaxResults(5)
.List<User>();
var users=session.CreateCriteria()
.SetFirstResult(100)
.SetMaxResults(5)
.List();
105条记录将在数据库服务器和负责剥离前100条记录的应用程序之间传输。对于包含许多行的表,这可能是一个问题
我已经验证过,对于数据库,NHibernate利用偏移量
和限制
关键字在数据库级别过滤结果。我知道在SQLServer2000中没有等价的OFFSET
关键字和Oracle的ROWNUM
,但是有解决方法吗?SQL Server 2005/2008怎么样?Nhibernate足够聪明,可以优化查询。如果选择前10行,它将使用TOP
语句。如果您选择的不是第一行,则它将使用RowNum
在sql 2000中没有RowNum
函数,这就是为什么在常规查询中无法选择所需行数的原因。对于sql 2000,正如我所知道的那样,使用了这样的优化视图
在sql 2005/2008中,查询将仅选择所需的行
Microsoft SQL Server使用的SQL语言变体T-SQL没有限制
子句。它有一个selecttop{…}
修饰符,您可以看到NHibernate在SQLServer2000中利用了这个修饰符
在SQL Server 2005中,Microsoft引入了Row_Number()over(order by{…})
函数,该函数可替代limit
子句,您可以看到NHibernate在SQL Server 2005/2008中利用了这一点
对SQLite的查询可能如下所示
select c.[ID], c.[Name]
from [Codes] c
where c.[Key] = 'abcdef'
order by c.[Order]
limit 20 offset 40
select c.[ID], c.[Name]
from (
select c.[ID], c.[Name], c.[Order]
, [!RowNum] = Row_Number() over (order by c.[Order])
from [Codes] c
where c.[Key] = 'abcdef'
) c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]
with
[Source] as (
select c.[ID], c.[Name], c.[Order]
, [!RowNum] = Row_Number() over (order by c.[Order])
from [Codes] c
where c.[Key] = 'abcdef'
)
select c.[ID], c.[Name]
from [Source] c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]
而针对SQLServer2005的类似查询可能如下所示
select c.[ID], c.[Name]
from [Codes] c
where c.[Key] = 'abcdef'
order by c.[Order]
limit 20 offset 40
select c.[ID], c.[Name]
from (
select c.[ID], c.[Name], c.[Order]
, [!RowNum] = Row_Number() over (order by c.[Order])
from [Codes] c
where c.[Key] = 'abcdef'
) c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]
with
[Source] as (
select c.[ID], c.[Name], c.[Order]
, [!RowNum] = Row_Number() over (order by c.[Order])
from [Codes] c
where c.[Key] = 'abcdef'
)
select c.[ID], c.[Name]
from [Source] c
where c.[!RowNum] > 40 and c.[!RowNum] <= 60
order by c.[Order]
我已经验证过,在sql 2005/2008中,NHibernate使用了row\u number()
函数。看来,使用SQL2000,我必须编写视图或存储过程才能达到同样的效果。谢谢你抽出时间。