2008-09-10 36 views

Trả lời

107

ICriteria có phương thức SetFirstResult(int i), cho biết chỉ mục của mục đầu tiên bạn muốn nhận (về cơ bản là hàng dữ liệu đầu tiên trong trang của bạn).

Nó cũng có phương thức SetMaxResults(int i), cho biết số hàng bạn muốn nhận (nghĩa là kích thước trang của bạn).

Ví dụ, đối tượng tiêu chí này nhận được 10 kết quả đầu tiên của lưới dữ liệu của bạn:

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

Điều này khá giống với cú pháp LINQ (NH) sẽ trông như thế nào - Tốt. – MotoWilliams

+13

Điều quan trọng cần lưu ý là bạn sẽ cần phải thực hiện một giao dịch riêng để truy xuất tổng số hàng để hiển thị máy nhắn tin của bạn. –

+1

Điều này thực hiện truy vấn SELECT TOP trong SQL Server. Hãy thử với SetFirstResult (1) .SetMaxResult (2); –

23

Cách sử dụng LINQ to NHibernate như được thảo luận trong this blog post bởi Ayende?

Mã mẫu:

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

Và đây là một bài chi tiết bởi đội ngũ blog của NHibernate trên Data Access With NHibernate bao gồm việc thực hiện phân trang.

+0

Note LINQ to Nhibernate là trong gói contrib và không bao gồm trong NHibernate Bản phát hành 2.0 – Richard

6

tôi đề nghị bạn nên tạo một cấu trúc cụ thể để đối phó với pagination. Giống như (tôi là một lập trình viên Java, nhưng đó phải là 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 một thực hiện, nhưng bạn có thể sử dụng các phương pháp được đề xuất bởi @Jon. Đây là một good discussion để bạn có một cái nhìn.

11

Rất có thể trong GridView, bạn sẽ muốn hiển thị một lát dữ liệu cộng với tổng số hàng (hàng đếm) của tổng lượng dữ liệu khớp với truy vấn của bạn.

Bạn nên sử dụng một MultiQuery để gửi cả truy vấn Chọn số (*) và .SetFirstResult (n) .SetMaxResult (m) truy vấn vào cơ sở dữ liệu của bạn trong một cuộc gọi duy nhất.

Lưu ý kết quả sẽ là danh sách chứa 2 danh sách, một danh sách cho lát dữ liệu và một cho số đếm.

Ví 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]; 
31
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 là có một cách khác để có được kết quả gõ từ MultiCriteria hoặc tất cả mọi người cũng làm như vậy giống như tôi?

Cảm ơn

87

Bạn cũng có thể tận dụng lợi thế của các tính năng tương lai trong NHibernate để thực hiện truy vấn để có được tổng kỷ lục đếm cũng như kết quả thực tế trong một truy vấn duy nhất.

Ví 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ó được tổng số hồ sơ, bạn làm như sau:

int iRowCount = rowCount.Value; 

Một cuộc thảo luận tốt về những gì tương lai cung cấp cho bạn là here.

+1

Công cụ tuyệt vời, cảm ơn –

+3

Điều này thật tuyệt. Tương lai hoạt động chính xác như đa chuẩn mà không có sự phức tạp cú pháp của đa chuẩn. – DavGarcia

+0

Sau khi đọc bài viết về tương lai tôi đang tự hỏi liệu tôi có nên sử dụng tương lai cho tất cả các truy vấn cơ sở dữ liệu của mình không ... Hạn chế là gì? :) – hakksor

39

Trong NHibernate 3 bạn có thể sử dụng QueryOver

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

Bạn cũng có thể muốn đặt hàng một cách rõ ràng kết quả của bạn như thế này:

var pageRecords = nhSession.QueryOver<TEntity>() 
      .OrderBy(t => t.AnOrderFieldLikeDate).Desc 
      .Skip(PageNumber * PageSize) 
      .Take(PageSize) 
      .List(); 
Các vấn đề liên quan