Как я могу выразить присоединение к сгруппированному подзапросу, используя NHibernate? - PullRequest
6 голосов
/ 09 ноября 2010

Я пытаюсь выразить SQL-запрос с помощью API критериев NHibernate, и у меня возникают трудности, потому что я думаю о базе данных, тогда как NHibernate ориентирован на объекты.

SQL (прекрасно работает):

select outerT.id, outerT.col1, outerT.col2, outerT.col3
from tbl outerT
inner join
    (select max(innerT.id)
     from tbl innerT
     group by innerT.col1) grpT
on outerT.id = grpT.id

По сути, это самостоятельное соединение таблицы с подмножеством самого себя. Я полагаю, я мог бы попытаться превратить само-соединение в ограничение:

select outerT.id, outerT.col1, outerT.col2, outerT.col3
from tbl outerT
where outerT.id in (select max(innerT.id) from tbl innerT group by innerT.col1)

Но я не уверен, как это выразить с помощью NHibernate; Я борюсь с ProjectionList от DetachedCriteria и хочу выбрать только max(id) при группировании по col1.

Большое спасибо за ваши предложения!

Ответы [ 2 ]

6 голосов
/ 01 июля 2011

Я не знаю, должен ли я опубликовать это как новый ответ или добавить его в качестве комментария к исходному вопросу, но я думаю, что решил эту проблему в этой теме:

Выбор подзапросов в NHibernate с Critieria API

1 голос
/ 30 июня 2011

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

Я понимаю, что вопрос требует, чтобы это былозакончил с использованием API Criteria, но я думал, что выложу версию HQL, которая может дать кому-то еще некоторые идеи.

var results = session.CreateQuery("from Product p where p.Id in (
    select max(p2.id)
from Product p2
group by p2.col1
)")

Я также обнаружил эту проблему JIRA, касающуюся API Criteria и не включающую группирование по столбцам в выборке.,В настоящее время, похоже, что то, чего вы хотите, вообще не может быть достигнуто с помощью API Criteria.

Группировать по свойству без добавления его в предложение select

UPDATE Используя пример из поста Monkey Coders, вы можете сделать следующее:

var subquery = DetachedCriteria.For<Product>("p")
.SetProjection(Projections.ProjectionList()
    .Add(Projections.GroupProperty("p.Col1"))
.Add(Restrictions.EqProperty("p2.Id", Projections.Max("p.Id"));

var query = DetachedCriteria.For<Product>("p2")
.Add(Subqueries.Exists(subquery));

, что приведет к следующему SQL

select *
from Product p2
where exists (
    select p.col1
    from Product p
    group by p.col1
    having p2.Id=max(p.Id)
)
...