Ответ 1
Ваше потенциальное решение будет обрабатываться в одной транзакции, но будет два вызова db. Если у вас должен быть только один вызов db, вы должны использовать многоэкранный/будущий запрос, как предлагалось. Дополнительную информацию о синтаксисе будущего см. В этом сообщении: http://ayende.com/blog/3979/nhibernate-futures.
Вот несколько способов выполнить ваш сценарий...
QueryOver (вызовы 2 дБ):var query = session.QueryOver<Organism>();
var result = query
.Skip((Page - 1) * PageSize)
.Take(PageSize)
.List();
var rowcount = query.RowCount();
С образцом набора из 100 организмов и запросом для организмов 11-20, вот два запроса, отправленные в db:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
SELECT count(*) as y0_ FROM Organism this_
QueryOver (вызов 1 дБ с будущим):
var query = session.QueryOver<Organism>()
.Skip((Page - 1) * PageSize)
.Take(PageSize)
.Future<Organism>();
var result = query.ToList();
var rowcount = session.QueryOver<Organism>()
.Select(Projections.Count(Projections.Id()))
.FutureValue<int>().Value;
Запрос для того же набора данных, что и раньше, это запрос, который сгенерирован:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;SELECT count(this_.Id) as y0_ FROM Organism this_;;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
Критерии (вызов 1 дБ с будущим):
var criteria = session.CreateCriteria<Organism>()
.SetFirstResult((Page - 1) * PageSize)
.SetMaxResults(PageSize)
.Future<Organism>();
var countCriteria = session.CreateCriteria<Organism>()
.SetProjection(Projections.Count(Projections.Id()))
.FutureValue<int>().Value;
Опять же, запрос для одного и того же набора данных, критерии с будущими результатами в том же запросе:
SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;SELECT count(this_.Id) as y0_ FROM Organism this_;;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]
Обратите внимание, что все три стиля запроса приводят к тем же самым точным запросам. Будущий синтаксис просто позволяет NHibernate выполнять один вызов базы данных, а не два.
Если вы используете NHibernate 3, я считаю, что самый элегантный способ справиться с этим - использовать новый синтаксис QueryOver. (Вы использовали старый синтаксис NHibernate.Linq в предлагаемом решении. Вам лучше изучить синтаксис QueryOver.)