.net 如何使用 NHibernate 进行分页?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can you do paging with NHibernate?
提问by Ray
For example, I want to populate a gridview control in an ASP.NET web page with only the data necessary for the # of rows displayed. How can NHibernate support this?
例如,我想在 ASP.NET 网页中填充 gridview 控件,仅使用显示的行数所需的数据。NHibernate 如何支持这一点?
回答by Jon Limjap
ICriteriahas a SetFirstResult(int i)method, which indicates the index of the first item that you wish to get (basically the first data row in your page).
ICriteria有一个SetFirstResult(int i)方法,它指示您希望获取的第一个项目的索引(基本上是页面中的第一个数据行)。
It also has a SetMaxResults(int i)method, which indicates the number of rows you wish to get (i.e., your page size).
它还有一个SetMaxResults(int i)方法,它指示您希望获得的行数(即您的页面大小)。
For example, this criteria object gets the first 10 results of your data grid:
例如,此标准对象获取数据网格的前 10 个结果:
criteria.SetFirstResult(0).SetMaxResults(10);
回答by Jeremy D
You can also take advantage of the Futures feature in NHibernate to execute the query to get the total record count as well as the actual results in a single query.
您还可以利用 NHibernate 中的 Futures 功能来执行查询以获取总记录数以及单个查询中的实际结果。
Example
例子
// 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>();
To get the total record count, you do the following:
要获得总记录数,请执行以下操作:
int iRowCount = rowCount.Value;
A good discussion of what Futures give you is here.
关于 Futures 给你什么的一个很好的讨论是在这里。
回答by Leandro de los Santos
From NHibernate 3 and above, you can use QueryOver<T>:
从 NHibernate 3 及更高版本,您可以使用QueryOver<T>:
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
You may also want to explicitly order your results like this:
您可能还想像这样明确地对结果进行排序:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
回答by Barbaros Alp
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); }
}
When paging data is there another way to get typed result from MultiCriteria or everyone does the same just like me ?
当分页数据时,是否有另一种方法可以从 MultiCriteria 中获取输入结果,或者每个人都像我一样做同样的事情?
Thanks
谢谢
回答by NotMyself
How about using Linq to NHibernate as discussed in this blog postby Ayende?
如Ayende 的这篇博文中所讨论的那样,如何使用 Linq 到 NHibernate ?
Code Sample:
代码示例:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
And here is a detailed post by the NHibernate team blog on Data Access With NHibernateincluding implementing paging.
这是 NHibernate 团队博客关于使用 NHibernate进行数据访问的详细帖子,包括实现分页。
回答by zadam
Most likely in a GridView you will want to show a slice of data plus the total number of rows (rowcount) of the total amount of data that matched your query.
在 GridView 中,您很可能希望显示数据切片加上与您的查询匹配的数据总量的总行数 (rowcount)。
You should use a MultiQuery to send both the Select count(*) query and .SetFirstResult(n).SetMaxResult(m) queries to your database in a single call.
您应该使用 MultiQuery 在一次调用中将 Select count(*) 查询和 .SetFirstResult(n).SetMaxResult(m) 查询发送到您的数据库。
Note the result will be a list that holds 2 lists, one for the data slice and one for the count.
请注意,结果将是一个包含 2 个列表的列表,一个用于数据切片,一个用于计数。
Example:
例子:
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];
回答by Marcio Aguiar
I suggest that you create a specific structure to deal with pagination. Something like (I'm a Java programmer, but that should be easy to map):
我建议您创建一个特定的结构来处理分页。类似于(我是 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()
}
I didn't supply an implementation, but you could use the methods suggested by @Jon. Here's a good discussionfor you to take a look.
回答by Marcin
You don't need to define 2 criterias, you can define one and clone it. To clone nHibernate criteria you can use a simple code:
您不需要定义 2 个条件,您可以定义一个并克隆它。要克隆 nHibernate 标准,您可以使用简单的代码:
var criteria = ... (your criteria initializations)...;
var countCrit = (ICriteria)criteria.Clone();

