Câu trả lời:
ICriteria
có một SetFirstResult(int i)
phương thức, cho biết chỉ mục của mục đầu tiên mà bạn muốn lấy (về cơ bản là hàng dữ liệu đầu tiên trong trang của bạn).
Nó cũng có một SetMaxResults(int i)
phương thức, cho biết số hàng bạn muốn lấy (tức là kích thước trang của bạn).
Ví dụ: đối tượng tiêu chí này nhận 10 kết quả đầu tiên của lưới dữ liệu của bạn:
criteria.SetFirstResult(0).SetMaxResults(10);
Bạn cũng có thể tận dụng tính năng Futures trong NHibernate để thực hiện truy vấn nhằm lấy tổng số bản ghi cũng như kết quả thực tế trong một truy vấn duy nhất.
Thí dụ
// 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>();
Để có tổng số bản ghi, bạn làm như sau:
int iRowCount = rowCount.Value;
Một cuộc thảo luận tốt về những gì Futures cung cấp cho bạn ở đây .
Từ NHibernate 3 trở lên, bạn có thể sử dụng QueryOver<T>
:
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
Bạn cũng có thể muốn sắp xếp các kết quả của mình một cách rõ ràng như thế này:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
.Skip(PageNumber * PageSize)
theo cách này, nếu kích thước trang là 10, nó sẽ không bao giờ truy xuất 10 hàng đầu tiên. Tôi đang chỉnh sửa để làm cho công thức chính xác. Giả sử rằng khái niệm, PageNumber
không nên 0. Nó tối thiểu phải đạt 1.
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); }
}
Khi phân trang dữ liệu có cách nào khác để nhận được kết quả đã nhập từ MultiCriteria hay mọi người cũng làm như tôi không?
Cảm ơn
Làm thế nào về việc sử dụng Linq để NHibernate như được thảo luận trong bài đăng trên blog này của Ayende?
Mẫu mã:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
Và đây là một bài đăng chi tiết của blog nhóm NHibernate về Truy cập dữ liệu Với NHibernate bao gồm cả việc triển khai phân trang.
Nhiều khả năng trong GridView, bạn sẽ muốn hiển thị một phần dữ liệu cộng với tổng số hàng (rowcount) của tổng lượng dữ liệu phù hợp với truy vấn của bạn.
Bạn nên sử dụng MultiQuery để gửi cả truy vấn Select count (*) và .SetFirstResult (n) .SetMaxResult (m) đến cơ sở dữ liệu của bạn trong một lần gọi.
Lưu ý rằng kết quả sẽ là một danh sách chứa 2 danh sách, một cho lát dữ liệu và một cho số lượng.
Thí dụ:
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];
Tôi khuyên bạn nên tạo một cấu trúc cụ thể để đối phó với việc phân trang. Một cái gì đó như (Tôi là một lập trình viên Java, nhưng điều đó sẽ dễ dàng để lập bản đồ):
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()
}
Tôi không cung cấp cách triển khai, nhưng bạn có thể sử dụng các phương pháp do @Jon đề xuất . Đây là một cuộc thảo luận tốt để bạn có thể xem qua.