解决关于NHibernate使用ICriteria分页时遇到的错误

简介:

最近在做一个项目,数据库访问层使用了NHibernate 2.1.0,因为项目中需要使用到分页取数据的功能,于是在Google上搜了一把如何使用NHibernate来获取分页数据。结果还真不少!不过除了介绍Hibernate的,差不多都千篇一律,看来不是某某高手的文章被过度转载,就是天下文章一大抄啊。先给两个链接大家可以看看:

http://www.cnblogs.com/scottpei/archive/2009/10/11/1580947.html

http://blog.csdn.net/loyayol/archive/2007/09/26/1802015.aspx

  既然大家都认同这个方法,偶就试试吧!

  将代码拷贝到我的工程中,稍作修改以适应项目的需要,然后写了一个测试页面运行,出错了!提示信息是Value cannot be null. Parameter name: projections 查了一下出错的代码,就在crit.SetProjection(null) ;这一行。看来还不能直接传null值进去。不清楚网上流传的这个版本大家都试过没有,明明就不对嘛,不过也有可能跟我所使用的NHibernate版本有关,这个可能在早期的版本中奏效吧。我也查了一下NHibernate 2.1.0的官方版本修改记录文档,说是对ICriteria.SetProjection()方法的参数做了一些修改。那这个问题怎么解决呢?

  我尝试着将这行代码去掉,结果在最后获取分页数据时报SQL语句语法错误,仔细看了下代码,这行的主要用途就是在通过crit.SetProjection(Projections.RowCount()).UniqueResult()方法取得总记录数后将SetProjection()方法所附加的条件去掉,否则下面继续使用该对象去获取分页数据时就会得到类似于这样的SQL语句:

  Select Top 5 Count(*) From MyTable

  这个在数据库中执行肯定是通不过的。看来在取得分页数据前必须将SetProjection()方法所附件的条件清除掉,可是查看ICriteria对象下面并没有提供这样的方法,SetProjection()方法所附加的条件又不能简单得去掉。后台看到一篇老外的文章,得到了一些启发,其实我们可以将ICriteria对象Clone一份,前一个对象专门用来返回总记录条数,Clone后的对象则专门用来取得分页数据,这样问题就可以完美解决了。下面是我整理后的代码,大家可以参考下。

复制代码
///   <summary>
///  Get the pagination product list.
///   </summary>
///   <param name="cateId"> Product category ID. </param>
///   <param name="currentPageIndex"> Current page index, begin with 1. </param>
///   <param name="pageSize"> Row count per page. </param>
///   <param name="recordCount"> Return the total record count from database. </param>
///   <returns> Return the paged product object list. </returns>
public  List < Products >  GetProducts( int ?  cateId,  int  currentPageIndex,  int  pageSize,  out   int  recordCount)
{            
    ICriteria crit 
=  Session.CreateCriteria( typeof (Products));
    
//  Set query condition.
    crit.Add(Restrictions.Eq( " Isdisabled " true ));
    
if  (cateId  !=   null )
    {
        crit.Add(Restrictions.Eq(
" Cateid.Id " , cateId));
    }

    
//  Copy current ICriteria instance to the new one for getting the pagination records.
    ICriteria pageCrit  =  CriteriaTransformer.Clone(crit);
    
    
//  Get the total record count
    recordCount  =  Convert.ToInt32(crit.SetProjection(Projections.RowCount()).UniqueResult());
                
    
// Set pagination
    pageCrit.AddOrder( new  Order( " Createdate " false ));  //  Set order parameter.
    pageCrit.SetFirstResult((currentPageIndex  -   1 *  pageSize).SetMaxResults(pageSize);
    
return  pageCrit.List < Products > ().ToList < Products > ();
 }
复制代码

  使用CriteriaTransformer.Clone()方法将ICriteria对象Clone一个副本。获取分页数据的逻辑仍然使用了网络上流传的那个版本中的代码。下面是测试代码:

ProductBll productBll  =   new  ProductBll();
int  recordCount;
List
< Products >  list  =  productBll.GetProducts( null 11 5 out  recordCount);

  如果没有where条件,可以将cateId的值设为null,第二个参数为当前的页码,从1开始,第三个参数是每页要显示的数据条数,最后一个参数是out类型的,在使用前只需要定义而不必初始化,用来获取总数据条数。


本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2009/11/09/1599053.html,如需转载请自行联系原作者

相关文章
|
6天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
Java 数据库连接 mybatis
Mybatis 分页插件 Pagehelper 的 PageInfo 字段属性解释
Mybatis 分页插件 Pagehelper 的 PageInfo 字段属性解释
615 0
|
Java 数据库连接 网络安全
SSH框架整合遇到的错误——Hibernate查询语句出现错误
在调试前台注册界面,填写注册信息,用户名Ajax异步验证时报错,报错文件在Dao文件的查询语句中。   报错信息: java.lang.IllegalArgumentException: org.hibernate.
2037 0
|
SQL Java 数据库连接
|
Java 数据库连接
hibernate辅助类含分页
1 package com.cy.utils; 2 3 import java.io.Serializable; 4 import java.util.Iterator; 5 import java.
743 0