Linq" .any" HQL中的等价物

时间:2015-01-22 16:34:52

标签: java linq hibernate nhibernate hql

我有一个NHibernate Linq查询,我需要将其翻译为HQL:

var result = Conexion.Session.Query<Person>();
result = result.Where(p => p.addresses.Any(a => a.City.Name == "mycity"));

返回在城市中至少拥有一个地址的人员#34; MyCity&#34;

我如何翻译&#34;任何&#34;条款为&#34; HQL sintax&#34;?

感谢。

2 个答案:

答案 0 :(得分:3)

这是等效的HQL:

select p 
from Person p
join p.addresses a
join a.city c
where c.name = :cityName

任何只需通过一对多联接来解决。

如果同一城市内有多个地址,要删除Person实体重复项,您需要使用distinct

select distinct p 
from Person p
join p.addresses a
join a.city c
where c.name = :cityName

select distinct p 
from Address a 
join fetch a.person p 
join a.city c 
where c.name = :cityName

答案 1 :(得分:3)

复制由以下内容生成的SQL:

var result = Conexion.Session.Query<Person>();
result = result.Where(p => p.addresses.Any(a => a.City.Name == "mycity"));

我们必须这样做:

var hql = "SELECT p FROM Person p WHERE EXISTS "
          + "(SELECT a FROM Address a "
          + "  LEFT JOIN a.City c "
          + "  WHERE p = a.Person " 
          + "    AND c.Name = 'mycity') ";

mycity 可以是参数:

var hql = "SELECT p FROM Person p WHERE EXISTS "
          + "(SELECT a FROM Address a "
          + "  LEFT JOIN a.City c "
          + "  WHERE p = a.Person " 
          + "    AND c.Name = :mycity) ";

var result = Conexion.Session.CreateQuery(hql)
        .SetParameter("mycity", "...")
        .List<Person()

如果AddressPerson的后引用,那将是有效的,因为这是条件的一部分 WHERE p = a.Person

如果该映射只包含从Person到Address的方式,那么hql必须是这样的:

var hql = "SELECT p FROM Person p WHERE EXISTS "
          + "(SELECT p2 FROM Person p2 "
          + "  LEFT JOIN p2.addresses a "
          + "  LEFT JOIN a.City c "
          + "  WHERE p = p2 " 
          + "    AND c.Name = :mycity) ";

即使地址与人之间的参考缺失,这也会有效