. any()带空值-当我期望为真时返回False

本文关键字:期望 False 返回 空值 any | 更新日期: 2023-09-27 17:53:05

我有一个视图模型,可为空的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);

你知道我做错了什么吗?

. any()带空值-当我期望为真时返回False

假设您的意思是"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