6

NHibernate の Criteria API を使用して SQL クエリを表現しようとしていますが、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 を使用してそれを表現する方法もわかりません。私は DetachedCriteria の ProjectionList と戦っており、max(id)グループ化中にのみ選択したいと考えていますcol1

ご提案いただきありがとうございます。

4

2 に答える 2

6

これを新しい回答として投稿するか、元の質問にコメントとして追加するかはわかりませんが、このスレッドで同様の問題を解決したと思います:

Criteria API を使用した NHibernate でのサブクエリの選択

于 2011-07-01T15:59:00.503 に答える
1

AFAIK you cannot join to subqueries at all in NHibernate but you can re-organise the query to use either an EXISTS or IN clause to replicate the same functionality.

I realise the question asks for this to be done using the Criteria API but I thought I would post a HQL version which may give someone else some ideas.

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

I also found this JIRA issue surrounding the Criteria API and not including group by columns in the select. Currently it looks like what you want cannot be achieved using the Criteria API at all.

Group By Property without adding it to the select clause

UPDATE Using the example from Monkey Coders post looks like you can do this:

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));

Which would produce the following SQL

select *
from Product p2
where exists (
    select p.col1
    from Product p
    group by p.col1
    having p2.Id=max(p.Id)
)
于 2011-06-30T08:56:05.943 に答える