Как вы можете выполнять пейджинг с помощью NHibernate?

StackOverflow https://stackoverflow.com/questions/54754

Вопрос

Например, я хочу заполнить элемент управления GridView на веб-странице ASP.NET только данными, необходимыми для отображаемого количества строк.Как NHibernate может это поддержать?

Это было полезно?

Решение

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();
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, как описано в этот пост в блоге от Айенде?

Пример кода:

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

А вот подробный пост в блоге команды NHibernate на Доступ к данным с помощью NHibernate включая реализацию пейджинга.

Скорее всего, в GridView вы захотите отобразить фрагмент данных плюс общее количество строк (rowcount) из общего объема данных, соответствующих вашему запросу.

Вам следует использовать MultiQuery для отправки запроса Select count(*) и запроса .SetFirstResult(n).SetMaxResult(m) в вашу базу данных за один вызов.

Обратите внимание, что результатом будет список, содержащий два списка: один для среза данных, а другой для счетчика.

Пример:

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()

}

Я не предоставил реализацию, но вы можете использовать методы, предложенные @Джон.Вот хорошая дискуссия чтобы ты посмотрел.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top