如何使用NHibernate进行分页?

如何使用NHibernate进行分页?

问题描述:

例如,我想在ASP.NET网页中填充一个gridview控件,只显示显示的行数所需的数据。 NHibernate如何支持这个?如何使用NHibernate进行分页?

ICriteria有一个SetFirstResult(int i)方法,它表示您希望获得的第一个项目(基本上是您的页面中的第一个数据行)的索引。

它也有一个SetMaxResults(int i)方法,这表明你希望得到(即页面大小)的行数。

例如,这个标准对象都将获得前10个结果数据网格:

criteria.SetFirstResult(0).SetMaxResults(10); 
+1

这几乎是Linq(至NH)语法看起来总是 - 尼斯。 – MotoWilliams 2008-09-17 05:04:15

+13

重要的是要注意,您将需要执行单独的事务来检索总行数以呈现您的寻呼机。 – 2009-01-07 00:44:45

如何通过Ayende在this blog post讨论使用LINQ to NHibernate的?

代码示例:

(from c in nwnd.Customers select c.CustomerID) 
     .Skip(10).Take(10).ToList(); 

这里是一个详细的职位由NHibernate的团队博客上Data Access With NHibernate包括实现分页。

+0

注意的LINQ to NHibernate的是在contrib包并没有包含在NHibernate的2.0版本 – Richard 2008-09-23 08:54:36

我建议你创建一个专门的机构来处理分页。喜欢的东西(我是一个Java程序员,但应该很容易地图):

public class Page { 

    private List results; 
    private int pageSize; 
    private int page; 

    public Page(Query query, int page, int pageSize) { 

     this.page = page; 
     this.pageSize = pageSize; 
     results = query.setFirstResult(page * pageSize) 
      .setMaxResults(pageSize+1) 
      .list(); 

    } 

    public List getNextPage() 

    public List getPreviousPage() 

    public int getPageCount() 

    public int getCurrentPage() 

    public void setPageSize() 

} 

我没有提供一个实现,但你可以使用由@Jon建议的方法。这里有一个good discussion供您参考。

最有可能在GridView中,您将希望显示一段数据加上与查询匹配的数据总量的总行数(rowcount)。

您应该使用MultiQuery在一次调用中将Select count(*)查询和.SetFirstResult(n).SetMaxResult(m)查询发送到数据库。

注意结果将是一个列表,其中包含2个列表,一个用于数据切片,另一个用于计数。

例子:

IMultiQuery multiQuery = s.CreateMultiQuery() 
    .Add(s.CreateQuery("from Item i where i.Id > ?") 
      .SetInt32(0, 50).SetFirstResult(10)) 
    .Add(s.CreateQuery("select count(*) from Item i where i.Id > ?") 
      .SetInt32(0, 50)); 
IList results = multiQuery.List(); 
IList items = (IList)results[0]; 
long count = (long)((IList)results[1])[0]; 

public IList<Customer> GetPagedData(int page, int pageSize, out long count) 
     { 
      try 
      { 
       var all = new List<Customer>(); 

       ISession s = NHibernateHttpModule.CurrentSession; 
       IList results = s.CreateMultiCriteria() 
            .Add(s.CreateCriteria(typeof(Customer)).SetFirstResult(page * pageSize).SetMaxResults(pageSize)) 
            .Add(s.CreateCriteria(typeof(Customer)).SetProjection(Projections.RowCountInt64())) 
            .List(); 

       foreach (var o in (IList)results[0]) 
        all.Add((Customer)o); 

       count = (long)((IList)results[1])[0]; 
       return all; 
      } 
      catch (Exception ex) { throw new Exception("GetPagedData Customer da hata", ex); } 
     } 

当寻呼数据是那里得到的多标准输入结果的另一种方式或者每个人都做了同样的我一样?

感谢

您也可以利用期货的NHibernate的功能来执行查询,以获得总记录数以及在单个查询的实际效果。

// Get the total row count in the database. 
var rowCount = this.Session.CreateCriteria(typeof(EventLogEntry)) 
    .Add(Expression.Between("Timestamp", startDate, endDate)) 
    .SetProjection(Projections.RowCount()).FutureValue<Int32>(); 

// Get the actual log entries, respecting the paging. 
var results = this.Session.CreateCriteria(typeof(EventLogEntry)) 
    .Add(Expression.Between("Timestamp", startDate, endDate)) 
    .SetFirstResult(pageIndex * pageSize) 
    .SetMaxResults(pageSize) 
    .Future<EventLogEntry>(); 

要获得总记录数,请执行以下操作:

int iRowCount = rowCount.Value; 

什么期货给你的是here了很好的讨论。

在NHibernate的3你可以使用QueryOver

var pageRecords = nhSession.QueryOver<TEntity>() 
      .Skip(PageNumber * PageSize) 
      .Take(PageSize) 
      .List(); 

你也可以明确地订购您的结果是这样的:

var pageRecords = nhSession.QueryOver<TEntity>() 
      .OrderBy(t => t.AnOrderFieldLikeDate).Desc 
      .Skip(PageNumber * PageSize) 
      .Take(PageSize) 
      .List();