Ваше потенциальное решение будет обработано в одной транзакции, но будет два вызова в дБ. Если у вас должен быть только один вызов БД, вы должны использовать запрос с несколькими запросами / в будущем, как это было предложено коллегами. Для получения дополнительной информации о будущем синтаксисе, проверьте этот пост: 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, вот два запроса, отправленных в базу данных:
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 дБ с Future):
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 дБ с Future):
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.)