NHibernate HQL逻辑问题

时间:2009-08-17 10:50:43

标签: nhibernate hql

我正在尝试编写一个NHibernate HQL查询,该查询在where子句中使用括号。但是,HQL解析器似乎忽略了我的括号,从而改变了我的语句的含义。任何人都可以解释这件事吗?

以下HQL查询:

from WebUser u left join fetch u.WebUserProfile left join fetch 
u.CommunicationPreferences where (u.CommunicationPreferences.Email = 0 and
u.SyncDate is not null) or u.DateDeleted is not null

转换为:

from   WebUser webuser0_
left outer join WebUserProfile webuserpro1_
on webuser0_.UserId = webuserpro1_.WebUserId
left outer join WebUserCommunicationPreferences communicat2_
on webuser0_.UserId = communicat2_.UserId
where  communicat2_.Email = 0
and (webuser0_.SyncDate is not null)
or webuser0_.DateDeleted is not null

由于

乔恩

2 个答案:

答案 0 :(得分:2)

我知道这是一个迟到的答案,但我不得不加两分钱。

在SQL中,and运算符优先于or运算符。 所以

  

(u.CommunicationPreferences.Email = 0   和u.SyncDate不为null)或   u.DateDeleted不为空

相同
  

communicat2_.Email = 0和   (webuser0_.SyncDate不为null)或   webuser0_.DateDeleted不为空

答案 1 :(得分:0)

您必须在where子句的所有标准中遵守您在from子句中指定的左连接。您必须在查询的所有部分中处理特殊的null情况,这是SQL(和HQL)的工作方式。

参考:http://en.wikipedia.org/wiki/Null_(SQL)

当您编写u.CommunicationPreferences.Email = 0时,CommunicationPreferences必须不为null,否则将不会选择数据库行。

我建议尝试以下方法(根据您自己的情况进行调整):

from WebUser u 
  left join fetch u.WebUserProfile w
  left join fetch u.CommunicationPreferences c
where ( (c.Email = 0 or c is null) 
         and u.SyncDate is not null) 
or u.DateDeleted is not null

从我们项目的HQL最佳实践中摘录:

  • 为所有到达的表格提供别名
  • 对于每个可为空的别名(在这种情况下为w和c),任何约束(c.Email = 0)都必须使用空案例(or c is null

已添加:详细说明:

第二个LEFT连接意味着即使没有匹配的CommunicationPreferences,也要选择WebUser。这与u.CommunicationPreferences.Email之类的选择不兼容,如果u.CommunicationPreferences为null,则排除任何匹配(请仔细阅读,我不参考电子邮件列)。

这种不兼容性可能导致奇怪的翻译,你不明白为什么以这种方式创建SQL ...修复HQL并再试一次:-)括号可能变得正确。