Відповіді:
ICriteria
має SetFirstResult(int i)
метод, який вказує на індекс першого елемента, який ви бажаєте отримати (в основному це перший рядок даних на вашій сторінці).
Він також має SetMaxResults(int i)
метод, який вказує кількість рядків, які ви хочете отримати (тобто розмір вашої сторінки).
Наприклад, цей об’єкт критеріїв отримує перші 10 результатів вашої сітки даних:
criteria.SetFirstResult(0).SetMaxResults(10);
Ви також можете скористатися функцією Futures в 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;
Гарне обговорення того, що дають вам майбутнє, - тут .
З NHibernate 3 і вище ви можете використовувати QueryOver<T>
:
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
Ви також можете чітко замовити результати так:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
.Skip(PageNumber * PageSize)
Таким чином, якщо розмір сторінки дорівнює 10, він ніколи не отримуватиме перші 10 рядків. Я редагую, щоб зробити формулу правильною. Якщо припустити, що концептуально PageNumber
це не повинно бути 0. Це повинно бути мінімум 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); }
}
Під час підключення даних є інший спосіб отримати набраний результат від MultiCriteria чи всі роблять те саме, як я?
Дякую
Як щодо використання Linq для NHibernate, як обговорювалося в цьому дописі блогу від Ayende?
Зразок коду:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
Ось детальний пост блогу команди NHibernate про доступ до даних до NHibernate, включаючи впровадження пейджингу.
Швидше за все, у GridView вам потрібно буде показати фрагмент даних плюс загальну кількість рядків (кількість рядків) від загальної кількості даних, яка відповідає вашому запиту.
Ви повинні використовувати 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];
Я пропоную вам створити конкретну структуру для вирішення проблем з пагинацією. Щось на кшталт (я програміст 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 . Ось хороша дискусія для вас, щоб подивитися.