【问题标题】:How can I express joining to a grouped subquery using NHibernate?如何使用 NHibernate 表达加入分组子查询?
【发布时间】:2011-05-06 22:25:06
【问题描述】:

我正在尝试使用 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 作斗争,并且只想在按 col1 分组时选择 max(id)

非常感谢您的建议!

【问题讨论】:

  • 你真的需要使用 Criteria 吗? HQL 可能更合适。
  • 老实说,对于这些类型的查询 - 节省您的头发并使用 HQL 或只是简单的旧 SQL(使用 CreateSqlQuery)。
  • 由于子查询产生的是标量集合而不是映射实体,我将如何在 HQL 中表达联接?

标签: nhibernate criteria criteria-api detachedcriteria


【解决方案1】:

我不知道是否应该将其作为新答案发布或将其添加为对原始问题的评论,但我认为我已在此线程中解决了类似的问题:

Selecting on Sub Queries in NHibernate with Critieria API

【讨论】:

    【解决方案2】:

    AFAIK 您根本无法在 NHibernate 中加入子查询,但您可以重新组织查询以使用 EXISTS 或 IN 子句来复制相同的功能。

    我知道问题要求使用 Criteria API 完成此操作,但我想我会发布一个 HQL 版本,这可能会给其他人一些想法。

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

    我还发现这个 JIRA 问题与 Criteria API 相关,并且在选择中不包括 group by 列。目前看来,使用 Criteria API 根本无法实现您想要的。

    Group By Property without adding it to the select clause

    更新 使用 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)
    )
    

    【讨论】:

    • 感谢您加入。您发布的是我的第二个版本(使用 IN)的良好 HQL 翻译,但我想知道 JOIN 版本的 HQL 会是什么样子。有什么深刻的想法吗?
    • @David Rubin - 目前 NHibernate 不支持这些类型的连接(例如,连接到 HQL、Criteria、QueryOver 或 LINQ 中的子查询)。虽然 IN 子句会给你几乎相同的查询计划。
    • @David Rubin - 在 MoneyCoder 的帮助下,我有一个标准版本的查询,它给出了相同的结果。
    • Mark Perry - 在我看来,您正在尝试使用 MonkeyCoder 的答案来获得赏金奖励。代码非常相似,我很确定您直接复制了代码(“var query = DetachedCriteria.For..” - 您刚刚将 Item 替换为 Product 但忘记了这个)。我认为应该通知一些版主。赏金就是赏金!绝对反对。
    • 我在我的回答中以及通过评论他的回答以及在他链接到的答案中支持他的回答时都将这个想法归功于 Monkeycoder。我只是根据他的工作更新了我的答案。不确定我是否应该为此投反对票。另外,在 monkeycoder 发布答案之前,我尝试使用 hql 回答问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多