使用Critieria API在NHibernate中选择子查询

所以我有一个具有以下结构的SQL查询:

select p.* from ( select max([price]) as Max_Price, [childId] as childNodeId from [Items] group by [childId] ) as q inner join [Items] as p on p.[price] = q.[Max_Price] and p.[childId] = q.[childNodeId] 

我需要使用Criteria API在NHibernate中重新创建此查询。 我尝试使用子查询API,但似乎要求内部查询返回单个列以检查与外部查询中的属性的相等性。 但是,我回来了两个。 我已经读过这可以通过HQL API完成,但我需要使用Criteria API来完成,因为我们将动态生成这样的查询。 任何人都可以引导我朝着正确的方向前进吗?

我通过稍微调整原始的sql查询设法解决了类似的问题。 我最终得到了这样的东西(伪sql代码):

 SELECT p.* FROM [Items] as p WHERE EXISTS ( SELECT [childId] as childNodeId FROM [Items] as q WHERE p.[childId] = q.[childNodeId] GROUP BY q.[childId] HAVING p.[price] = MAX(q.[price]) ) 

这是QueryOver实现:

 var subquery = QueryOver.Of(() => q) .SelectList(list => list.SelectGroup(() => q.ChildId)) .Where(Restrictions.EqProperty( Projections.Property(() => p.Price), Projections.Max(() => q.Price))) .And(Restrictions.EqProperty( Projections.Property(() => p.ChildId), Projections.Property(() => q.ChildId))); 

从这里你只需要传递别名,以便NHibernate可以正确解析实体(伪代码):

 var filter = QueryOver.Of(() => p) .WithSubquery.WhereExists(GetSubQuery(p, criteria...)); 

我希望这有助于您的具体情况。

更新: Criteria API

 var subquery = DetachedCriteria.For("q") .SetProjection(Projections.ProjectionList() .Add(Projections.GroupProperty("q.ChildId"))) .Add(Restrictions.EqProperty("p.Price", Projections.Max("q.Price"))) .Add(Restrictions.EqProperty("p.ChildId", "q.ChildId")); var query = DetachedCriteria.For("p") .Add(Subqueries.Exists(subquery)); 

不过我建议坚持使用QueryOver版本,它更直观,你可以避免魔术字符串(特别是你不必升级NH版本)。

如果这对你有用,请告诉我。