关于.net:如何使用NHibernate进行分页?

关于.net:如何使用NHibernate进行分页?

How can you do paging with NHibernate?

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


ICriteria具有SetFirstResult(int i)方法,该方法指示希望获取的第一项的索引(基本上是页面中的第一数据行)。

它还具有SetMaxResults(int i)方法,该方法指示您希望获取的行数(即页面大小)。

例如,此条件对象获取数据网格的前10个结果:

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

您还可以利用NHibernate中的Futures功能来执行查询,以获取单个记录中的总记录数以及实际结果。

1
2
3
4
5
6
7
8
9
10
11
 // 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>();

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

1
int iRowCount = rowCount.Value;

这里对期货给您带来了很好的讨论。


在NHibernate 3及更高版本中,您可以使用QueryOver< T >

1
2
3
4
var pageRecords = nhSession.QueryOver<TEntity>()
            .Skip((PageNumber - 1) * PageSize)
            .Take(PageSize)
            .List();

您可能还想像这样显式地排序结果:

1
2
3
4
5
var pageRecords = nhSession.QueryOver<TEntity>()
            .OrderBy(t => t.AnOrderFieldLikeDate).Desc
            .Skip((PageNumber - 1) * PageSize)
            .Take(PageSize)
            .List();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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); }
      }

当分页数据时,还有另一种方法可以从MultiCriteria获取类型化的结果,或者每个人都像我一样吗?

谢谢


如Ayende在此博客文章中所讨论的,如何使用Linq进行NHibernate?

代码样例:

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

这是NHibernate团队博客上有关使用NHibernate进行数据访问的详细文章,包括实现分页。


最有可能在GridView中显示一个数据切片,再加上与查询匹配的数据总量的总行数(行数)。

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

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

例:

1
2
3
4
5
6
7
8
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];

我建议您创建一个特定的结构来处理分页。类似的东西(我是Java程序员,但是应该很容易映射):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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建议的方法。这是一个很好的讨论,供您查看。


您无需定义2个条件,您可以定义一个条件并将其克隆。
要克隆nHibernate条件,可以使用简单的代码:

1
2
var criteria = ... (your criteria initializations)...;
var countCrit = (ICriteria)criteria.Clone();


推荐阅读

    linux编译时显示命令?

    linux编译时显示命令?,系统,基础,工具,代码,百度,下来,网上,命令,内核,文件,L

    显示linux网卡命令行?

    显示linux网卡命令行?,系统,信息,工具,网络,服务,电脑,网卡,技术指标,地址,

    linux命令显示内容?

    linux命令显示内容?,标准,系统,数据,命令,百度,实时,时间,信息,文件,内容,lin

    linux常用显示命令?

    linux常用显示命令?,工作,地址,系统,信息,管理,命令,目录,标准,功能,常用命

    linux命令行同步显示?

    linux命令行同步显示?,地址,工具,系统,数据,工作,时间,命令,综合,网址,信息,L

    linux数据库查找命令?

    linux数据库查找命令?,位置,名称,状态,服务,软件,信息,系统,命令,名字,密码,

    linux分页显示命令?

    linux分页显示命令?,工具,通信,命令,数据,信息,管道,标准,位置,一致,系统,lin

    linux数据库同步命令?

    linux数据库同步命令?,信息,系统,汽车,车辆,服务,工作,通信,一致,分析,数据,D

    linux中ps命令显示?

    linux中ps命令显示?,系统,信息,状态,进程,命令,多地,软件,工作,基础,报告,lin

    linux命令逐页显示?

    linux命令逐页显示?,系统,工作,地址,命令,网上,信息,百度,基础,标准,内容,在l

    linux显示内核命令?

    linux显示内核命令?,地址,发行,信息,工具,电脑,系统,名称,内核,版本,状态,如

    显示等号linux命令?

    显示等号linux命令?,工作,地址,信息,系统,命令,目录,标准,管理,基础,常用命

    linux中显示路径命令?

    linux中显示路径命令?,系统,地址,工作,信息,时间,命令,数据,网络,路径,名字,l

    linux显示的命令行?

    linux显示的命令行?,信息,标准,数据,命令,实时,系统,时间,名称,文件,文件名,l

    linux浏览网页的命令?

    linux浏览网页的命令?,工作,系统,传播,地址,命令,环境,发行,信息,网络,基础,l

    linux建立数据库命令?

    linux建立数据库命令?,软件,系统,工作,数据,密码,工具,数据库,一致,网络,服

    linux命令多显示几行?

    linux命令多显示几行?,实时,系统,标准,数据,档案,命令,文件,最新,信息,状态,l

    linux命令进数据库?

    linux命令进数据库?,地址,系统,名字,服务,密码,命令,读法,数据库,操作系统,

    linux命令行显示键值?

    linux命令行显示键值?,系统,环境,管理,文化,国家,信息,工具,数据,软件,项目,L

    linux用命令显示键盘?

    linux用命令显示键盘?,系统,信息,工具,电脑,键盘,分析,设备,数据,通用,工作,L