HQL:OR子句返回的记录少而不是更多

时间:2018-02-21 19:57:09

标签: nhibernate hql

我有一个Employee模型,它有一个Manager字段,可以为null,或者指向另一个Employee。

我试图运行一个查询,该查询将撤回位于层次结构中某个Manager下方的Employees列表。所以我从以下WHERE子句开始:

(e.Manager.Id = :managerId or 
  (e.Manager is not null and e.Manager.Manager.Id = :managerId))

这似乎工作正常,返回员工的经理是指定的经理,或者经理是由指定的经理管理的。

我尝试将它提升到一个新的水平:

(e.Manager.Id = :managerId or 
  (e.Manager is not null and e.Manager.Manager.Id = :managerId) or 
  (e.Manager.Manager is not null and e.Manager.Manager.Manager.Id = :managerId))

然后,只返回指定经理管理的经理的员工。由指定经理管理的员工不会被退回。

这怎么可能?当然,如果条款的第一部分是匹配的(由指定的经理管理),那么该条款的其余部分是否应该不被评估?

2 个答案:

答案 0 :(得分:1)

如果您没有比您在问题中提到的更多级别的管理,那么此SQL语句应该有效。

select e1.* from Employee e1 
left join Employee manager on e1.manager = manager.id
left join Employee bigManager on manager.manager = bigManager.id
where e1.manager = 3 or manager.manager = 3 or bigManager.manager = 3

3只是我在db中测试时使用的管理器的ID

答案 1 :(得分:1)

如果没有明确的JOIN,有时Hibernate会丢失并且无法生成开发人员认为应该生成的查询。

所以,一个好的做法总是明确你的JOIN(正如@Badzen所建议的那样)。

我无法测试查询,但请尝试:

Select e FROM Employee e
LEFT JOIN e.manager m1
LEFT JOIN m1.manager m2
LEFT JOIN m2.manager m3
WHERE m1.id = :managerId 
   or (m1 IS NOT NULL and m2.id = :managerId) 
   or (m2 IS NOT NULL and m3.id = :managerId) 

通过这种方式,生成的查询是可预测的,并且更容易理解问题在哪里。