为什么null和引用null不是一回事

时间:2011-06-09 19:44:26

标签: entity-framework c#-4.0 null nullable

为什么这两种方法的工作方式不同:

    public List<Foo> GetFoos()
    {
        int? parentId = null;
        var l = _dataContext.Foos.Where(x => x.ParentElementId == parentId).ToList();
        return l;
    }

    public List<Foo> GetFoos()
    {
        var l = _dataContext.Foos.Where(x => x.ParentElementId == null).ToList();
        return l;
    }

第一个没有返回。第二次返回预期的结果。数据来自EF。 ParentElementId可以为空。

3 个答案:

答案 0 :(得分:4)

那是因为你无法在SQL中与null进行比较,它有一个特殊的IS NULL运算符来检查空值。

第一个查询将被转换为比较,其中参数为null:

WHERE ParentElementId = @param

这不起作用,因为比较两个空值不会产生真。

第二个查询将被转换为空检查,因为空值是常量:

WHERE ParentElementId IS NULL

这是有效的,因为EF不会被欺骗将其转化为比较。

答案 1 :(得分:2)

我知道,你得到了答案,但这里有一些额外的见解:

  • 此问题已在MSDN forums上讨论过。有些人认为这是一个错误,其他人则认为这是出于性能原因的故意行为
  • 总是有助于运行EFProf或Sql Server Profiler(如果您正在使用SQL Server。例如,您的两个示例分别转换为以下两个语句:

    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ParentElementId] AS [ParentElementId]
    FROM [dbo].[Foo] AS [Extent1]
    WHERE [Extent1].[ParentElementId] = NULL
    
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[ParentElementId] AS [ParentElementId]
    FROM [dbo].[Foo] AS [Extent1]
    WHERE [Extent1].[ParentElementId] IS NULL
    

这种技术(查看生成的SQL)在处理EF中的问题时通常非常有用。

答案 2 :(得分:0)

Captain Obvious:因为parentId可能不是null

回复编辑:第一个不可编辑。不能输入类型为null。

对其他编辑的回复:因为EF查询错误地翻译了可空类型