NHibernate 与 SQL Server 分页
当使用 SetFirstResult(start)
和 SetMaxResults(count)
方法实现分页时,我注意到生成的查询仅执行 select top count * from some_table< /code> 并且它不考虑
start
参数,或者至少不考虑数据库级别。看起来,如果我指示 NHibernate 执行以下查询:
var users = session.CreateCriteria<User>()
.SetFirstResult(100)
.SetMaxResults(5)
.List<User>();
105 条记录将在数据库服务器和应用程序之间传输,应用程序将小心地删除前 100 条记录。对于包含许多行的表,这可能是一个问题。
我已经验证,使用 SQLite 数据库 NHibernate 可以利用 OFFSET
和 < code>LIMIT 关键字在数据库级别过滤结果。我知道 SQL Server 2000 中没有与 OFFSET
关键字和 Oracle 的 ROWNUM
等效的关键字,但是有什么解决方法吗? SQL Server 2005/2008 怎么样?
When using SetFirstResult(start)
and SetMaxResults(count)
methods to implement paging I've noticed that the generated query only does a select top count * from some_table
and it does not take the start
parameter into account or at least not at the database level. It seems that if I instruct NHibernate to execute the following query:
var users = session.CreateCriteria<User>()
.SetFirstResult(100)
.SetMaxResults(5)
.List<User>();
105 records will transit between the database server and the application which will take care to strip the first 100 records. With tables containing many rows this could be a problem.
I've verified that with an SQLite database NHibernate takes advantage of the OFFSET
and LIMIT
keywords to filter results at the database level. I am aware that there's no equivalent of the OFFSET
keyword and Oracle's ROWNUM
in SQL Server 2000 but is there any workaround? How about SQL Server 2005/2008?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
T-SQL 是 Microsoft SQL Server 使用的 SQL 语言的变体,没有
limit
子句。它有一个select top {...}
修饰符,您可以看到 NHibernate 在 SQL Server 2000 中利用了该修饰符。在 SQL Server 2005 中,Microsoft 引入了
Row_Number() over (order by {. ..})
函数,它可以用作limit
子句的替代,您可以看到 NHibernate 在 SQL Server 2005/2008 中利用了该功能。SQLite 的查询可能看起来像,
而 SQL Server 2005 的类似查询可能看起来像
,或者使用公共表表达式,它可能看起来像
SQL Server 2000 中也有一种方法可以做到这一点
T-SQL, the variant of the SQL language which Microsoft SQL Server uses, does not have a
limit
clause. It has aselect top {...}
modifier which you see NHibernate taking advantage of with SQL Server 2000.With SQL Server 2005, Microsoft introduced the
Row_Number() over (order by {...})
function which can be used as a replacement to thelimit
clause, and you can see NHibernate taking advantage of that with SQL Server 2005/2008.A query for SQLite might look like
while a similar query for SQL Server 2005 might look like
or, using Common Table Expressions, it might look like
There is a way to do it in SQL Server 2000 as well
Nhibernate 足够聪明,可以优化查询。如果您选择前 10 行,它将使用
TOP
语句。如果您选择的不是第一行,那么它将使用RowNum
。在sql 2000中没有
RowNum
函数,这就是为什么通常的查询不可能选择所需的行数。据我所知,对于 sql 2000,使用了这样的优化视图。在 sql 2005/2008 中,查询将仅选择所需的行。
Nhibernate is smart enough to optimize query. If you select first 10 rows it will use
TOP
statement. If you select not first rows then it will useRowNum
.In sql 2000 there is no
RowNum
function, that's why it is impossible with usual query to select required number of rows. For sql 2000 as I know for such an optimization views were used.In sql 2005/2008 query will select only required rows.