代码之家  ›  专栏  ›  技术社区  ›  Darin Dimitrov

使用SQL Server进行NHibernate分页

  •  13
  • Darin Dimitrov  · 技术社区  · 15 年前

    SetFirstResult(start) SetMaxResults(count) 实现分页的方法我注意到生成的查询只执行 select top count * from some_table start 参数,至少不在数据库级别。如果我指示NHibernate执行以下查询:

    var users = session.CreateCriteria<User>()
                       .SetFirstResult(100)
                       .SetMaxResults(5)
                       .List<User>();
    

    105条记录将在数据库服务器和负责剥离前100条记录的应用程序之间传输。对于包含许多行的表,这可能是一个问题。

    SQLite 数据库NHibernate利用 OFFSET LIMIT 抵消 关键词与甲骨文 ROWNUM 在SQLServer2000中,是否有解决方法?SQL Server 2005/2008怎么样?

    2 回复  |  直到 15 年前
        1
  •  16
  •   yfeldblum    15 年前

    T-SQL是Microsoft SQL Server使用的SQL语言的变体,它没有 limit select top {...} 您看到NHibernate在SQL Server 2000中利用的修饰符。

    在SQLServer2005中,Microsoft引入了 Row_Number() over (order by {...}) 限制 子句,您可以看到NHibernate在SQLServer2005/2008中利用了这一点。

    对SQLite的查询可能如下所示

    select c.[ID], c.[Name]
    from [Codes] c
    where c.[Key] = 'abcdef'
    order by c.[Order]
    limit 20 offset 40
    

    而针对SQLServer2005的类似查询可能如下所示

    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]
    

    select c.[ID], c.[Name]
    from (
        select top 20 c.[ID], c.[Name], c.[Order]
        from (
            select top 60 c.[ID], c.[Name], c.[Order]
            from [Codes] c
            where c.[Key] = 'abcdef'
            order by c.[Order]
        ) c
        order by c.[Order] desc
    ) c
    order by c.[Order]
    
        2
  •  4
  •   BenMorel Manish Pradhan    11 年前

    Nhibernate足够聪明,可以优化查询。如果选择前10行,它将使用 TOP 陈述如果您选择的不是第一行,则它将使用 RowNum .

    在sql 2000中,没有 罗努姆