最近用NHibernate做个项目 由于数据库用
![](/icons/71477de.gif)
是mssql2000 NHibernate 对mssql2000
![](/icons/71477de.gif)
分页查询支持
![](/icons/71477de.gif)
不是很好 于是自己动手实现
![](/icons/71477yi.gif)
个mssql2000方言
原 NHibernate.Dialect 命名空间下
![](/icons/71477de.gif)
mssql2000
![](/icons/71477de.gif)
方言类 MsSql2000Dialect 里
![](/icons/71477de.gif)
GetLimitString 思路方法 如下:
Code
public override SqlString GetLimitString(SqlString querySqlString,
![](/icons/71477int.gif)
off
![](/icons/71477set.gif)
,
![](/icons/71477int.gif)
limit)
{
![](/icons/71477if.gif)
(off
![](/icons/71477set.gif)
> 0)
{
throw
![](/icons/71477new.gif)
NotSupportedException("SQL Server does not support an off
![](/icons/71477set.gif)
");
}
/*
* "SELECT TOP limit rest-of-sql-statement"
*/
![](/icons/71477return.gif)
querySqlString.Insert(GetAfterSelectInsertPo
![](/icons/71477int.gif)
(querySqlString), " top " + limit.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
);
}
看上面这段代码大家都知道这种分页方式
![](/icons/71477de.gif)
性能有多么
![](/icons/71477de.gif)
差 下面我把我自己实现
![](/icons/71477de.gif)
方言类代码贴出来
Code
public
![](/icons/71477class.gif)
mySqlServer2000Dialect : MsSql2000Dialect
{
private
![](/icons/71477int.gif)
GetFromIndex(SqlString querySqlString)
{
![](/icons/71477string.gif)
subselect = querySqlString.GetSubselectString
![](/icons/71477kh.gif)
.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
;
![](/icons/71477int.gif)
fromIndex = querySqlString.IndexOfCaseInsensitive(subselect);
![](/icons/71477if.gif)
(fromIndex
![](/icons/71477dd.gif)
-1)
{
fromIndex = querySqlString.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.ToLowerInvariant
![](/icons/71477kh.gif)
.IndexOf(subselect.ToLowerInvariant
![](/icons/71477kh.gif)
);
}
![](/icons/71477return.gif)
fromIndex;
}
private
![](/icons/71477string.gif)
RemoveSortOrderDirection(
![](/icons/71477string.gif)
sortExpression)
{
// Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc".
![](/icons/71477return.gif)
Regex.Replace(sortExpression.Trim
![](/icons/71477kh.gif)
, @"(\)|\s)(?i:asc|desc)$", "$1").Trim
![](/icons/71477kh.gif)
;
}
public override bool SupportsLimitOff
{
get
{
![](/icons/71477return.gif)
true;
}
}
public override NHibernate.SqlCommand.SqlString GetLimitString(SqlString querySqlString,
![](/icons/71477int.gif)
off
![](/icons/71477set.gif)
,
![](/icons/71477int.gif)
limit)
{
![](/icons/71477if.gif)
(off
![](/icons/71477dd.gif)
0)
{
![](/icons/71477return.gif)
base.GetLimitString(querySqlString, off
![](/icons/71477set.gif)
, limit);
}
SqlString myQuery =
![](/icons/71477new.gif)
SqlString(RemoveSortOrderDirection(querySqlString.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.ToLower
![](/icons/71477kh.gif)
));
![](/icons/71477int.gif)
orderIndex = myQuery.LastIndexOfCaseInsensitive(" order by ");
![](/icons/71477if.gif)
(orderIndex <= 0)
{
throw
![](/icons/71477new.gif)
NotSupportedException("must spec
![](/icons/71477if.gif)
y 'order by' statement to support limit operation with off
![](/icons/71477set.gif)
in SqlServer2000");
}
![](/icons/71477string.gif)
orderBy = myQuery.Sub
![](/icons/71477string.gif)
(orderIndex).
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.Trim
![](/icons/71477kh.gif)
;
![](/icons/71477string.gif)
![](/icons/71477zhk2.gif)
sortExpressions = myQuery.Sub
![](/icons/71477string.gif)
(orderIndex).
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.Trim
![](/icons/71477kh.gif)
.Sub
![](/icons/71477string.gif)
(9).Split(',');
![](/icons/71477int.gif)
fromIndex = GetFromIndex(myQuery);
SqlString from = myQuery.Sub
![](/icons/71477string.gif)
(fromIndex, orderIndex - fromIndex).Trim
![](/icons/71477kh.gif)
;
![](/icons/71477string.gif)
fromAsName = from.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.Sub
![](/icons/71477string.gif)
(from.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.IndexOf(' ', 5)).Trim
![](/icons/71477kh.gif)
;
SqlString select = myQuery.Sub
![](/icons/71477string.gif)
(0, fromIndex);
![](/icons/71477int.gif)
PageSize = limit - off
![](/icons/71477set.gif)
;
SqlStringBuilder result =
![](/icons/71477new.gif)
SqlStringBuilder
![](/icons/71477kh.gif)
;
result.Add("declare @indextable table(id
![](/icons/71477int.gif)
identity(1,1),nid
![](/icons/71477int.gif)
)
![](/icons/71477set.gif)
rowcount " + limit.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
);
result.Add(" insert
![](/icons/71477int.gif)
o @indextable(nid) select");
result.Add(" " + RemoveSortOrderDirection(sortExpressions[0]).Replace(fromAsName,"t") + " " + from.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
.Replace(fromAsName,"t") + " " + orderBy.Replace(fromAsName,"t") + " desc ");
result.Add(" " + select.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
+ " " + from.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
+ ",@indextable a where " + RemoveSortOrderDirection(sortExpressions[0]) + " = a.nid and a.[id] between " + (off
![](/icons/71477set.gif)
+ 1).
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
+ " and " + limit.
![](/icons/71477ToString.gif)
![](/icons/71477kh.gif)
);
![](/icons/71477return.gif)
result.ToSqlString
![](/icons/71477kh.gif)
;
}
}
这个类继承自原 NHibernate
![](/icons/71477de.gif)
mssql2000方言类 重写了 SupportsLimitOff
![](/icons/71477set.gif)
属性 返回 true 让 NHibernate 支持 off
重写了 GetLimitString 思路方法 使用 内存变量表
![](/icons/71477de.gif)
方式进行数据分页 前提是 hql 语句里必须带有主键排序字段 主键必须是 自动增长
下面介绍如何使用这个类来替换 NHibernate 下
![](/icons/71477de.gif)
原mssql2000方言:
在NHibernate配置文件里
![](/icons/71477de.gif)
找到 <property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
替换成 <property name="dialect">myMsSql2000Dialect类
![](/icons/71477de.gif)
命名空间.myMsSql2000Dialect</property>
哪位高人有更好
![](/icons/71477de.gif)
实现方式
![](/icons/71477de.gif)
话 别忘了共享给我下