为什么这两种方法的工作方式不同:
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
可以为空。
答案 0 :(得分:4)
那是因为你无法在SQL中与null进行比较,它有一个特殊的IS NULL
运算符来检查空值。
第一个查询将被转换为比较,其中参数为null:
WHERE ParentElementId = @param
这不起作用,因为比较两个空值不会产生真。
第二个查询将被转换为空检查,因为空值是常量:
WHERE ParentElementId IS NULL
这是有效的,因为EF不会被欺骗将其转化为比较。
答案 1 :(得分:2)
我知道,你得到了答案,但这里有一些额外的见解:
总是有助于运行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查询错误地翻译了可空类型