NHibernate分页查询在SQL Server 2012上的应用

3
根据这个问题:

https://nhibernate.jira.com/browse/NH-3038

NHibernate应该为SQL Server 2012创建高效的分页查询。
我使用NHibernate 3.3.3GA。我在配置文件中设置了方言:
 <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>

在调试时,我发现会话工厂确实具有 MsSql2012Dialect

但是以下代码仍然存在:

session.Query<TestEntity>().Skip(1).Take(1).ToList()

生成与旧的SQL Server 2008方言相同的T-SQL:
exec sp_executesql N'
SELECT TOP (@p0) EntityId1_, Version1_, Name1_, Something1_ 
FROM (select testentity0_.EntityId as EntityId1_, testentity0_.Version as Version1_, testentity0_.Name as Name1_, testentity0_.Something as Something1_, ROW_NUMBER() 
OVER(ORDER BY CURRENT_TIMESTAMP) 
as __hibernate_sort_row from tTestEntity testentity0_) as query
WHERE query.__hibernate_sort_row > @p1
ORDER BY query.__hibernate_sort_row',N'@p0 int,@p1 int',@p0=1,@p1=1

如何让NHibernate Linq提供程序使用MsSql2012Dialect的分页功能并生成一个带有OFFSETFETCH的查询?

解决方案:

感谢Diego Mijelshon将我引导到正确的源代码,我成功实现了一个快速修复程序,似乎工作得很好。我们已经使用它几个月了,目前没有问题。

这是我所做的:

我从NHibernate源代码中导入了以下类到我的库中:

https://github.com/nhibernate/nhibernate-core/blob/967091f5c22a16a576f46144055f78c0f373ffcd/src/NHibernate/SqlCommand/Parser/SqlTokenizerExtensions.cs https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Dialect/MsSql2012Dialect.cs https://github.com/nhibernate/nhibernate-core/blob/967091f5c22a16a576f46144055f78c0f373ffcd/src/NHibernate/SqlCommand/Parser/SqlTokenizer.cs https://github.com/nhibernate/nhibernate-core/blob/967091f5c22a16a576f46144055f78c0f373ffcd/src/NHibernate/SqlCommand/Parser/SqlParserUtils.cs https://github.com/nhibernate/nhibernate-core/blob/967091f5c22a16a576f46144055f78c0f373ffcd/src/NHibernate/SqlCommand/Parser/SqlToken.cs

据我记得,我进行了一些修改以删除不必要的代码片段。 在SqlTokenizerExtensions中,我只保留了这两个扩展:
public static bool TryParseUntil(this IEnumerator<SqlToken> tokenEnum, string keyword)
public static bool TryParseUntilFirstMsSqlSelectColumn(this IEnumerator<SqlToken> tokenEnum)

SqlTokenizer、SqlToken、SqlParserUtils、MsSql2012Dialect - 无更改。

然后我只需在NHibernate的配置文件中将<property name="dialect">设置为新的MsSql2012Dialect,现在我的分页查询变得简洁明了。

1个回答

3

有一个问题:这个MsSql2012Dialect的源代码包含对NHibernate.SqlCommand.Parser的引用,但最新的v3.3.3GA似乎缺少它。所以我不确定是否可以重用这个新的MsSql2012Dialect。看起来,他们在NH4中实现了一些重大变化,这使得仅重用他们代码的一部分变得困难。 - JustAMartin
好的观点。那么可能就是要从源代码编译NH了。 - Diego Mijelshon
我花了几个小时检查代码并收集SqlParser的部分。我只需要在我的程序集中导入3或4个文件才能编译MsSql2012Dialect。明天我们将进行一些深入测试,但从第一眼看来,一切似乎都很好。感谢您引领我到NHibernate源代码。 - JustAMartin
@Martin,你的自定义NH进展如何?你愿意在某个地方发布源代码/DLL吗?我遇到了与你原始帖子中相同的分页问题。谢谢! - Tyler Forsythe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接