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

标签 c# .net sql 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...));

我希望这对您的具体情况有所帮助。

更新:标准 API

var subquery = DetachedCriteria.For<Items>("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<Items>("p")
    .Add(Subqueries.Exists(subquery));

尽管如此,我还是建议您坚持使用 QueryOver 版本,它更加直观并且您可以避免使用魔法字符串(尤其是您不必升级 NH 版本)。

请告诉我这是否适合您。

关于c# - 使用 Critieria API 在 NHibernate 中选择子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6541229/

相关文章:

c# - 使用正则表达式抓取'\'之后的部分

c# - 将 Task.Factory.StartNew 与采用单个 int 参数的 Action 结合使用

asp.net - 将 MVC 2 项目升级到 MVC 5

.net - 为什么不同版本的 Silverlight 程序集具有相同的版本号?

C# 获取主音量级别/百分比

sql - 在不使用 max 的情况下从 count 中查找最大值

php - SQL 左连接 - 右表中的多行

c# - 具有 LostFocus 触发器的元素上的显式 UpdateSource

c# - 我需要做什么来设置 Visual Studio 以便能够操作 Excel 文件?

mysql - 在 SELECT 中重命名列多个 id