1

我对以下方法有疑问:

public IQueryable<Customer> ListCustomers(int? parentId)
{
    Debug.Assert(parentId == null);
    //var list = _customerRepository.List().Where(c => c.ParentId == null);
    var list = _customerRepository.List().Where(c => c.ParentId == parentId);
    return list;
}

我的数据库中有一个客户,其 ParentId 为 null。当我用 , 调用方法时ListCustomers(null)listreturn 语句为空。如果我交换注释掉的行并使用硬编码的空值进行查询,则列表包含我的一个客户。

什么可能导致这两个查询之间存在这种差异?为什么c.ParentId == parentId不返回任何东西的那个?

4

3 回答 3

1

因为 Nullable 类型,linq 提供程序不会生成正确的 IS NULL 检查。有关更多信息,请参阅此答案:https ://stackoverflow.com/a/785501/1195510

于 2012-12-08T12:28:10.953 回答
1

EF 将您的查询翻译int?成如下内容:

DECLARE @parentId Int = null
SELECT ... WHERE ParentId = @parentId

当这在数据库上执行时,它不会做你所期望的,因为在 SQL[column] = NULL中总是错误的。

我同意 EF 可以更好地处理这个问题,但作为一种解决方法,您可以编写如下内容:

.Where( c => !parentId.HasValue
  ? !c.ParentId.HasValue 
  : c.ParentId.Value == parentId.Value
)

然后,EF 将生成带有正确IS NULL谓词的(有些冗长的)SQL 语句。

于 2012-12-08T12:47:25.043 回答
0

对于可为空的类型,您必须像这样使用它:

 .Where(c=> object.Equals(c.ParentId, parentId))
于 2012-12-08T12:28:51.180 回答