NHibernate: hql для запроса критериев - нужна помощь - PullRequest
0 голосов
/ 17 сентября 2009

У меня есть HQL-запрос, который прекрасно работает:

            select m 

            from Media m

            join m.Productlines p
            join m.Categories c                
            join m.Spaces sp
            join m.Solutions so

            where m.Uid != 0
            and p.Uid in (:productlines)
            and c.Uid in (13)                
            and sp.Uid in (52)
            and so.Uid in (15,18)

            group by m.Uid

Но теперь его нужно параметризовать / сделать динамическим, не только параметры, но и объединения (можно выбирать только из мультимедиа, без каких-либо объединений, поэтому в этом случае не потребуется * .Uid in) ).

Я не хочу возиться с экземпляром StringBuilder и строить запрос hql таким образом, я бы предпочел использовать Criteria API, но я не могу получить

SELECT m.*
....
GROUP BY m.Uid

запрос для работы с критериями.

Если я добавлю

Projections.GroupProperty("Uid") 

на мой запрос nhibernate выбирает

SELECT m.Uid
....
GROUP BY m.Uid

что, конечно, неправильно.

После этого мне также нужно подсчитать уникальных строк, возвращаемых запросом, как результат разбитого на страницы.

Итак, мой другой запрос довольно похож, но я не могу найти критерий, эквивалентный

SELECT COUNT(DISTINCT m.Uid)

Вот HQL:

            select count(distinct m.Uid) 

            from Media m

            join m.Productlines p
            join m.Categories c                
            join m.Spaces sp
            join m.Solutions so

            where m.Uid != 0
            and p.Uid in (:productlines)
            and c.Uid in (13)                
            and sp.Uid in (52)
            and so.Uid in (15,18)

Как это можно сделать с помощью Criteria API?

Пожалуйста, (N) эксперты Hibernate - помогите мне, я не могу найти работающее решение. Любая помощь с благодарностью!

Ответы [ 2 ]

2 голосов
/ 17 сентября 2009

Групповые столбцы неявно возвращаются как результат, но вы можете добавить больше столбцов. AFAIK, вы можете вернуть полные лица:

var query = session.CreateCriteria(typeof(Media), "m")
  .Add(Projections.GroupProperty("m"))
  .Add(Restrictions.NotEq("m.Uid", 0));

// dynamically add filters
if (filterProductLines)
{
  query
    .CreateCriteria("m.Productlines", "p")
    .Add(Restrictions.Eq("p.Uid", productLines));
}
// more dynamic filters of this kind follow here...

IList<Media> results = query.List<Media>();

Для подсчета полного количества результатов вы можете просто составить один и тот же запрос с другой проекцией:

var query = session.CreateCriteria(typeof(Media), "m")
    .SetProjection(Projections.CountDistinct("m.Uid"));
// rest of the query the same way as above

long totalNumberOfResults = query.UniqueResult<long>();

Я не уверен насчет Projections.GroupProperty("m"), тебе нужно попробовать это. Если это не работает, вы можете сделать его DetachedQuery, который возвращает только идентификаторы:

var subquery = DetachedCriteria.For(typeof(Media), "m")
  .Add(Projections.GroupProperty("m.Uid"))
  .Add(Restrictions.NotEq("m.Uid", 0));
// add filtering

var query = session.CreateCriteria(typeof(Media), "outer")
  .Add(Subqueries.PropertyIn("outer.Uid", subquery));

IList<Media> results = query.List<Media>();

Это создает SQL-запрос, подобный этому:

select outer.* // all properties of Media to create an instance
from Media outer
where outer.Uid in (
  select Uid
  from media m
  where // filter
)
1 голос
/ 17 сентября 2009
var count = session.CreateCriteria(typeof(Media))
    // Add other criterias...
    .SetProjection(Projections.CountDistinct("Id")) // or whatever the id property of Media class is called
    .UniqueResult<long>();

Что касается вопроса GROUP BY, запрос:

SELECT m.*
....
GROUP BY m.Uid

не имеет смысла, потому что вам нужно выбирать только столбцы, которые появляются в группе по выражениям или агрегатным функциям. Не могли бы вы подробнее рассказать о том, чего именно вы пытаетесь достичь?

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