.Any() 与 Nullables - 当我期望 True 时返回 False

发布于 2024-11-03 10:23:25 字数 580 浏览 1 评论 0原文

我有一个带有可为 null 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);

知道我在这里做错了什么吗?

I have a view model with a nullable int...

public ObjectViewModel (){
    public int? Total
}

... and there are several rows in my DB where the total is null.

Despite that, this always returns 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

But the following returns true (as expected):

bool exists = repo.All().Any(r => r.Total == null);

Any idea what I am doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

旧人 2024-11-10 10:23:25

假设您的意思是“vm.Total is null”,并且 All() 是一个拼写错误...

我认为您的问题在于将其转换为 SQL 的方式:

  • 第一个查询使用 r.Total = @param1 转换为 WHERE 子句,
  • 第二个查询使用 IS NULL 转换为 WHERE 子句

MSDN 对 NULL 有很好的描述

NULL 值表示该值为
未知。 NULL 值是不同的
从空值或零值。没有两个
空值是相等的。比较
两个空值之间,或一个
NULL 和任何其他值,返回
未知,因为每个 NULL 的值
未知。

这意味着您不能在 SQL 中使用比较运算符,因此也不能在 Linq to sql 中使用。

解决这个问题的一些方法是:

Assuming you meant "vm.Total is null" and that All() was a typo...

I think your problem is the way this is translated into SQL:

  • the first query gets translated as a WHERE clause with r.Total = @param1
  • the second query gets translated as a WHERE clause using IS NULL

MSDN has a good description on NULL:

A value of NULL indicates the value is
unknown. A value of NULL is different
from an empty or zero value. No two
null values are equal. Comparisons
between two null values, or between a
NULL and any other value, return
unknown because the value of each NULL
is unknown.

This means that you cannot use Comparison operators in SQL - and hence also you can't in Linq to sql either.

Some ways around this are:

淡看悲欢离合 2024-11-10 10:23:25

乔希的回答对我来说似乎是最准确的。只需使用空合并运算符:

bool exists = repo.AllRows().Any(r => r.Total ?? 0 == vm.Total ?? 0);

...,您将不再有一种“WHERE NULL = NULL”,而是“WHERE 0 = 0”,这是可以的。

Josh's answer seems the most accurate to me. Simply use the null coalescing operator :

bool exists = repo.AllRows().Any(r => r.Total ?? 0 == vm.Total ?? 0);

... and you won't have a kind of "WHERE NULL = NULL" anymore, but a "WHERE 0 = 0" which is okay.

榆西 2024-11-10 10:23:25

正如 Bala R 所说,如果 vm 为 null,那么您将无法访问 Total 属性,并且它必须抛出 NullReferenceException。

您的查询应该是:

bool exists = repo.Any(r => r.Total == null);

如果 Total 属性中至少有一条包含 null 的记录,则 exists 将为 true。

As Bala R says, if vm is null so you'll not be able to access to Total property and it must throw NullReferenceException.

Your query should be:

bool exists = repo.Any(r => r.Total == null);

exists will be true if there is a record at least with null in Total property.

雨巷深深 2024-11-10 10:23:25

您的代码应该给出异常,但无论哪种方式您都可以尝试:

Any(r => r.Total == vm==null ? null : vm.Total)

Your code should give an exception but either way you could try:

Any(r => r.Total == vm==null ? null : vm.Total)
孤独患者 2024-11-10 10:23:25

如果集合中的任何项目满足 lambda 指定的条件,Any 方法将返回 true。因此,repo 中没有一个项目的 Total 等于 vm.Total,但是有些项目为 null,因此第二个返回 true。

为了进行验证,在其中添加了一些调试代码,

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

The Any method returns true if any of the items in your collection meet the condition specified by the lambda. So none of the items in repo have a Total which equals vm.Total however there are items which are null so the second returns true.

To verify, thrown a little debug code in there,

Console.WriteLine("vm.Total=" + vm.Total.ToString());
foreach (var r in repo)
    Console.WriteLine("r.Total=" r.Total == null ? "null" : r.Total.ToString());

And take a look at the items, you should not see r.Total which is equal to vm.Total and you will see at least one null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文