Что Вы пытаетесь сделать? Возможно, существует лучший Perl способ сделать независимо от того, что Вы пытаетесь выполнить.
, Например, если Вы не хотите людей, слоняющихся без дела в Ваших объектах, потому что Вы хотите осуществить инкапсуляцию, можно использовать что-то как Класс:: InsideOut. Тот модуль имеет Класс:: InsideOut:: О модуле документации, который объясняет понятие. Существует также Объект:: InsideOut, который уже упомянул Brian Phillips.
Я думаю, что это невозможно в критериях, у него есть некоторые ограничения.
Вы можете получить идентификатор и загрузить элементы в следующем запросе:
var query = Session
.CreateCriteria<Item>("item")
.SetProjection(Projections.ProjectionList()
.Add(Projections.SqlFunction("rowcount", NHibernateUtil.Int32))
.Add(Projections.Id()));
Если вам это не нравится используйте HQL, вы также можете установить максимальное количество результатов:
IList<Item> result = Session
.CreateQuery("select item, rowcount() from item where ..." )
.SetMaxResult(100)
.List<Item>();
Используйте CreateMultiCriteria.
Таким образом можно выполнить 2 простых оператора с одним обращением к БД.
Мне интересно, почему использование критериев является обязательным. Разве вы не можете использовать session.CreateSQLQuery? Если вы действительно должны сделать это в одном запросе, я бы предложил вернуть объекты Item и счетчик, например:
select {item.*}, count(*) over()
from Item {item}
... таким образом вы можете вернуть объекты Item из своего запроса вместе со счетчиком. Если у вас возникла проблема с кешированием Hibernate,
Если я правильно понимаю ваш вопрос, у меня есть решение. Я немного боролся с этой же проблемой.
Позвольте мне кратко описать мою проблему, чтобы убедиться, что мы находимся на одной странице. Моя проблема сводилась к перелистыванию страниц. Я хочу отобразить 10 записей в пользовательском интерфейсе, но я также хочу знать общее количество записей, соответствующих критериям фильтра. Я хотел сделать это с помощью API критериев NH, но при добавлении проекции для количества строк мой запрос больше не работал, и я не получал никаких результатов (я не помню конкретную ошибку, но это похоже на то, что вы получаем)
Вот мое решение (скопируйте и вставьте из моего текущего производственного кода). Обратите внимание, что «SessionError» - это имя бизнес-объекта, для которого я получаю выгружаемые данные, согласно 3 критериям фильтра: IsDev, IsRead и IsResolved.
ICriteria crit = CurrentSession.CreateCriteria(typeof (SessionError))
.Add(Restrictions.Eq("WebApp", this));
if (isDev.HasValue)
crit.Add(Restrictions.Eq("IsDev", isDev.Value));
if (isRead.HasValue)
crit.Add(Restrictions.Eq("IsRead", isRead.Value));
if (isResolved.HasValue)
crit.Add(Restrictions.Eq("IsResolved", isResolved.Value));
// Order by most recent
crit.AddOrder(Order.Desc("DateCreated"));
// Copy the ICriteria query to get a row count as well
ICriteria critCount = CriteriaTransformer.Clone(crit)
.SetProjection(Projections.RowCountInt64());
critCount.Orders.Clear();
// NOW add the paging vars to the original query
crit = crit
.SetMaxResults(pageSize)
.SetFirstResult(pageNum_oneBased * pageSize);
// Set up a multi criteria to get your data in a single trip to the database
IMultiCriteria multCrit = CurrentSession.CreateMultiCriteria()
.Add(crit)
.Add(critCount);
// Get the results
IList results = multCrit.List();
List<SessionError> sessionErrors = new List<SessionError>();
foreach (SessionError sessErr in ((IList)results[0]))
sessionErrors.Add(sessErr);
numResults = (long)((IList)results[1])[0];
Итак, я создаю свои базовые критерии с дополнительными ограничениями. Затем я КЛОНИРУЮ его и добавляю прогноз количества строк к КЛОНИРОВАННЫМ критериям. Обратите внимание, что я клонирую его до того, как добавляю ограничения на подкачку. Затем я настраиваю IMultiCriteria для хранения исходных и клонированных объектов ICriteria и использую IMultiCriteria для их выполнения. Теперь у меня есть выгружаемые данные из исходных ICriteria (и я перетаскивал только те данные, которые мне нужны по сети), а также необработанный подсчет количества фактических записей, соответствующих моим критериям (полезно для отображения или создания ссылок на страницы или чего-то еще). Эта стратегия мне понравилась. Надеюсь, это поможет.
и добавьте проекцию количества строк в КЛОНИРОВАННЫЕ критерии. Обратите внимание, что я клонирую его до , я добавляю ограничения на подкачку. Затем я настраиваю IMultiCriteria, чтобы содержать исходные и клонированные объекты ICriteria, и использую IMultiCriteria для их выполнения. Теперь у меня есть выгружаемые данные из исходных ICriteria (и я перетаскивал только те данные, которые мне нужны по сети), а также необработанный подсчет количества фактических записей, соответствующих моим критериям (полезно для отображения или создания ссылок на страницы или чего-то еще). Эта стратегия мне очень понравилась. Надеюсь, это поможет. и добавьте проекцию количества строк в КЛОНИРОВАННЫЕ критерии. Обратите внимание, что я клонирую его до , я добавляю ограничения на подкачку. Затем я настраиваю IMultiCriteria, чтобы содержать исходные и клонированные объекты ICriteria, и использую IMultiCriteria для их выполнения. Теперь у меня есть выгружаемые данные из исходных ICriteria (и я перетаскивал только те данные, которые мне нужны по сети), а также необработанный подсчет количества фактических записей, соответствующих моим критериям (полезно для отображения или создания ссылок на страницы или чего-то еще). Эта стратегия мне понравилась. Надеюсь, это поможет. Теперь у меня есть выгружаемые данные из исходных ICriteria (и я перетаскивал только те данные, которые мне нужны по сети), а также необработанный подсчет количества фактических записей, соответствующих моим критериям (полезно для отображения или создания ссылок на страницы или чего-то еще). Эта стратегия мне понравилась. Надеюсь, это поможет. Теперь у меня есть выгружаемые данные из исходных ICriteria (и я перетаскивал только те данные, которые мне нужны по сети), а также необработанный подсчет количества фактических записей, соответствующих моим критериям (полезно для отображения или создания ссылок на страницы или чего-то еще). Эта стратегия мне очень понравилась. Надеюсь, это поможет.Я бы посоветовал исследовать настраиваемый преобразователь результатов, вызвав SetResultTransformer () в вашем сеансе.
Создайте свойство формулы в сопоставлении классов:
<property name="TotalRecords" formula="count(*) over()" type="Int32" not-null="true"/>;
IList<...> result = criteria.SetFirstResult(skip).SetMaxResults(take).List<...>();
totalRecords = (result != null && result.Count > 0) ? result[0].TotalRecords : 0;
return result;