【问题标题】:Linq selecting on string value "not equals" ignores DB nullsLinq 选择字符串值“不等于”会忽略 DB 空值
【发布时间】:2014-03-27 10:19:24
【问题描述】:

这里有些奇怪。通过实体框架访问的数据表有一个可以为空的字符串/varchar 的字段。

当您尝试使用 Linq 选择事物以获取不等于给定值的项目时,即

var thingsToRun = rep.Things.Where(t => t.Status != "Running");

您得到的是所有状态为“正在运行”之外的所有事物的列表除了那些状态为空的事物。

换句话说,如果您有三个状态为“正在运行”、“未运行”和 NULL 的事物,则上述查询将只返回一个状态为“未运行”的项目。

我认为这与 C# null 和 DB null 之间的不匹配有关。但这似乎很奇怪。有什么简单的方法吗?

编辑:感谢您的回答。仍然好奇为什么会发生这种情况?

【问题讨论】:

  • 您要省略空值还是要获取它们?一般来说,这与 C# 或 LINQ 无关,而是与您的数据库有关。通常,如果您不明确搜索它们,数据库永远不会返回空记录:WHERE Status IS NULL 或 Status IS NOT NULL。所以一个空值既不是=也不是!=,它根本就没有定义。

标签: c# sql linq entity-framework


【解决方案1】:

在查询中包含 null

var thingsToRun = rep.Things.Where(t => t.Status == null || t.Status != "Running");

【讨论】:

    【解决方案2】:

    您可以显式测试null:

    var thingsToRun
        = rep.Things.Where(t => t.Status == null || t.Status != "Running");
    

    至于为什么,Tim 在他的 cmets 中提供了一个很好的答案。为了更完整的答案,我会在这里放一些东西。数据库土地中的值null 通常不等于任何东西,也不“不等于”任何东西。无论哪种方式,它都无法与任何价值相提并论。

    我不能说这是每个数据库对待null的方式,但通常如果您有一个包含三个记录的数据库,使用您的示例,“正在运行”、“未运行” ",然后为空

    ... WHERE some_column = 'RUNNING'   <- returns one record
    ... WHERE some_column <> 'RUNNING'  <- returns one record
    ... WHERE some_column IS NULL       <- returns one record
    

    如果您能够在 LINQ 语句上放置一个断点并查看生成的 SQL 在对象中的任何位置是否可见,那么您可能能够准确判断发生了什么。我猜你会看到== null 被翻译成IS NULL。

    【讨论】:

      【解决方案3】:

      因为 null != Running 未定义:既不是真也不是假。

      您可能想查看this thread.

      【讨论】:

        猜你喜欢
        • 2018-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多