代码之家  ›  专栏  ›  技术社区  ›  DanP

如何使用hql匹配所有子项

  •  3
  • DanP  · 技术社区  · 14 年前

    选择父实体(不同)列表的最佳/首选方法是什么?父实体的子集合包含子参数列表中所有项的匹配项?

    我正在执行“任意”版本的搜索,如下所示:

    select p.Id, p.Name from parent p 
    where exists(from p.Children c where c in (:childList))
    

    然而,我对如何最好地执行这个搜索的“全部”版本有点困惑。目前,我正在为每个我对匹配感兴趣的孩子动态创建HQL;类似这样:

    select p.Id, p.Name from parent p 
    where :child1 in elements(p.Children)
    and   :child2 in elements(p.Children)
    -- etc...
    

    我情不自禁地认为有更好的方法可以做到这一点;有人能指出我的正确方向吗?

    作为参考,我使用的是NHibernate 2.1.2

    2 回复  |  直到 14 年前
        1
  •  2
  •   James Kovacs    14 年前

    有趣的问题,我没有找到一个简单的答案。在(:childlist)“中使用”all elements(p.children)“的简单尝试未能生成有效的SQL。这个怪物最后工作了…

    var query = session.CreateQuery("select p from Parent p join p.Children c where c in (:childList) group by p.Id, p.Name having count(p) = :childListSize");
    var children = new[] {session.Load<Child>(1),session.Load<Child>(2),session.Load<Child>(3)};
    query.SetParameterList("childList", children);
    query.SetParameter("childListSize", children.Length);
    

    让我们打开HQL…

    select p from Parent p 
    join p.Children c 
    where c in (:childList) 
    group by p.Id, p.Name 
    having count(p) = :childListSize
    

    我们正在创建一个与子级的内部联接,它产生多行,选择子级在子级列表中的那些行,按父级分组,并查看是否获得了预期的行数,并且只返回那些父级。唷!

    请注意,必须显式指定GroupBy中的所有属性。否则,nh只包括id和group by失败。

    顺便说一句,我用它来对付NH3,虽然我想不出任何理由它不能和NH2.1.2一起工作。

        2
  •  1
  •   Jaguar    14 年前

    您可以查询子级并选择父级,只要关联存在,就可以这样…

    select distinct c.Parent.Id, c.Parent.Name from Child c 
    where c in (:childList))