Как вы можете сделать пейджинг с NHibernate? - PullRequest
106 голосов
/ 10 сентября 2008

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

Ответы [ 7 ]

110 голосов
/ 10 сентября 2008

ICriteria имеет метод SetFirstResult(int i), который указывает индекс первого элемента, который вы хотите получить (в основном, первую строку данных на вашей странице).

Он также имеет метод SetMaxResults(int i), который указывает количество строк, которое вы хотите получить (т. Е. Размер вашей страницы).

Например, этот критерий получает первые 10 результатов вашей сетки данных:

criteria.SetFirstResult(0).SetMaxResults(10);
87 голосов
/ 25 августа 2009

Вы также можете воспользоваться функцией Futures в NHibernate для выполнения запроса, чтобы получить общее количество записей, а также фактические результаты в одном запросе.

* ** 1003 тысяча два * Пример
 // 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;

Хорошее обсуждение того, что дает вам Фьючерс: здесь .

45 голосов
/ 22 февраля 2011

В 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();
31 голосов
/ 11 января 2009
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, или все делают то же самое, что и я?

Спасибо

23 голосов
/ 10 сентября 2008

Как насчет использования Linq для NHibernate, как описано в этом сообщении в блоге Ayende?

Пример кода:

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

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

11 голосов
/ 26 сентября 2008

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

Вы должны использовать 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];
6 голосов
/ 10 сентября 2008

Я предлагаю вам создать определенную структуру для разбивки на страницы. Что-то вроде (я программист на 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 . Вот вам хорошее обсуждение , чтобы вы могли на него взглянуть.

...