HQL 子查询的意外空返回

本文关键字:返回 意外 查询 HQL | 更新日期: 2023-09-27 18:32:45

我已经在我的C# Web应用程序中使用NHibernate完成了OR映射。当我想获取所有叶节点时,我使用如下查询语句:

List<NODE> LeafList =(List<NODE>) Session.CreateQuery("from NODE as node where node.Id not in (select FatherNodeId from NODE)").List<NODE>();

但是,查询后我得到的 LeafList 计数等于 0。我的数据库是这样的:

Id FatherNodeId
1   NULL
3    1
4    3
5    3

因此,我的预期结果应该是 id 为 4 或 5 的节点。更令人困惑的是,如果我将"not in"更改为"in",查询效果很好,并返回 id 为 1 或 3 的节点。

那么我不在子查询中有什么问题呢?

HQL 子查询的意外空返回

使用Not exist关键词

试试这个.

from NODE as node where node.Id not exists ( select  FatherNodeId from NODE)

那么我不在子查询中有什么问题?

这是一个非常重要的问题,因为一旦知道,在使用 NULL 值时就不应该忘记这个问题。

问题不在于 NH 或 .Net。它与涉及 NULL 的布尔表达式的语义有关。任何涉及 NULL 的布尔表达式永远不会为真(这并不意味着它总是假的),任何涉及结果的表达式都永远不会为真。

因此,这些查询(子句似乎总是为真)永远不会返回任何结果,因为它们永远不会解析为 true:

select 1 where (null=null) or not(null=null)
select 1 where (1=null) or not(1=null)
select 1 where (1<>null) or not(1<>null)

您的查询应该是这样的(不太熟悉 HQL)

from NODE as node 
    where not exists 
        ( from NODE as child where child.FatherNodeId = node.Id )