我有一个视图模型,可为空的int…
public ObjectViewModel (){
public int? Total
}
…并且在我的数据库中有几行总null。
尽管如此,这总是返回false:
bool exists = repo.AllRows() // renamed this for clarity; returns IQueryable
.Any(r => r.Total == vm.Total); // I know r.Total and vm.Total
// are both null
但是下面返回true(如预期):
bool exists = repo.All().Any(r => r.Total == null);
你知道我做错了什么吗?
假设您的意思是"vm "。Total是null",并且All()
是一个错别字…
我认为你的问题是如何将其转换为SQL:
- 第一个查询被翻译为带有
r.Total = @param1
的WHERE子句 - 第二个查询使用
IS NULL
转换为WHERE子句
MSDN对NULL:
有很好的描述NULL表示该值为未知的。NULL值是不同的从空值或零值。没有两个空值是相等的。比较在两个空值之间,或在a之间NULL和任何其他值,返回未知,因为每个值为NULL是未知的。
这意味着你不能在SQL中使用比较运算符,因此你也不能在Linq to SQL中使用比较运算符。
- 在虚拟机中测试null。
- 使用
Object.Equals
进行比较-有关此的更多信息,请参阅此博客文章- http://www.brentlamborn.com/post/LINQ-to-SQL-Null-check-in-Where-Clause.aspx
Josh的回答在我看来是最准确的。只需使用空合并操作符:
bool exists = repo.AllRows().Any(r => r.Total ?? 0 == vm.Total ?? 0);
…这样你就不会再有"WHERE NULL = NULL"了,而是"WHERE 0 = 0"
正如Bala R所说,如果vm是null,那么您将无法访问Total
属性,并且它必须抛出NullReferenceException。
你的查询应该是:
bool exists = repo.Any(r => r.Total == null);
Total
属性中至少有一条记录为null
,则 exists
为真。
你的代码应该给出一个异常,但是你可以尝试:
Any(r => r.Total == vm==null ? null : vm.Total)
如果集合中的任何项满足lambda指定的条件,则Any
方法返回true。所以repo
中没有一个项目的Total等于vm.Total
,但是有一些项目是空的,所以第二个返回真。
为了验证,在那里抛出了一些调试代码,
Console.WriteLine("vm.Total=" + vm.Total.ToString());
foreach (var r in repo)
Console.WriteLine("r.Total=" r.Total == null ? "null" : r.Total.ToString());
看一下项目,你应该不会看到r.Total
等于vm.Total
,你会看到至少一个null