【问题标题】:Warning says Linq-To-Sql Expression is always false, but this is incorrect, why?警告说 Linq-To-Sql 表达式总是错误的,但这是不正确的,为什么?
【发布时间】:2016-07-01 14:47:37
【问题描述】:

我在下面代码的注释中指出的行收到警告。我正在使用 Visual Studio 2015。我在数据库中有 2 个表,并使用 Linq-2-Sql 查询它们。 Linq 代码在 companyID 上的两个表之间执行左连接。

运行时,左连接按预期运行,我得到了 TestTable1 中的所有值,但只有 CompanyId 匹配的 TestTable2 中的记录。

如果下面的警告是正确的并且表达式总是错误的,那么字符串“NULL”将永远不会分配给 value1。情况并非如此,因为当我运行它时,我在执行左连接时会得到“NULL”。

我在代码中的很多地方都使用了这种模式,而且这些警告无处不在,但我的代码在我正在执行的 NULL 检查中运行良好。这个警告对我来说似乎是错误的。我在这里遗漏了什么吗?

t2.CompanyId 是一个 INT 类型的数据库字段。以及 linq-2-sql 类中的 int 数据类型,但在查询中仍以某种方式分配为 null。

    var db = new SandBoxDataContext();

    var result = (from t1 in db.TestTable1s

                  from t2 in db.TestTable2s
                    .Where(x => x.CompanyId == t1.CompanyId)
                    .DefaultIfEmpty()

                  select new
                  {
                      //t2.CompanyId == null in line below is underlined with the warning!
                      value1 = t2.CompanyId == null ? "NULL" : "INT"

                  }).ToList();

    foreach (var rec in result)
    {
        Response.Write("value1 = " + rec.value1 + "<br>");
    }

这里是警告

CS0472  The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'

下面是生成的SQL

SELECT 
    (CASE 
        WHEN ([t1].[CompanyId]) IS NULL THEN 'NULL'
        ELSE CONVERT(NVarChar(4),'INT')
     END) AS [value1]
FROM [dbo].[TestTable1] AS [t0]
LEFT OUTER JOIN [dbo].[TestTable2] AS [t1] ON [t1].[CompanyId] = [t0].[CompanyId]

【问题讨论】:

  • CompanyIDint 还是 int?
  • 数据库中的一个 int(一个 NOT NULL 列)和 Linq2Sql 类(一个 int 变量)
  • 那么它不能如警告所述为空
  • 你会想,但如果你运行代码你会发现它实际上可以为空
  • @Dancer321 不可能将null 实现为int - 所以这不会在您的代码中发生。此外,由于您的列被标记为NOT NULL,因此不可能有空值。尽管您的查询可能与 null 有关,但不可能通过 SQL 或 Linq2Sql 让 CompanyID 返回 NULL

标签: c# sql asp.net linq linq-to-sql


【解决方案1】:

警告是因为将任何int 表达式与null 进行比较总是false

这在查询表达式中可能有所不同。提供者可以翻译成它喜欢的任何东西。显然,尽管这是一个查询,但 C# 编译器仍然选择警告您。

我不知道 L2S 将其翻译成什么。您说它的工作原理很明显,翻译可以满足您的要求,并且警告是误报。

我建议您将其重写为使警告消失并增加过程中代码直观性的形式:

value1 = t2 == null ? "NULL" : "INT"

【讨论】:

  • 是的。您的更改删除了警告,并且代码仍然有效。提供者似乎以不同的方式对待 DefaultIfEmpty(),不返回 int 的默认值,而是返回 null。
  • 对,LINQ 提供程序在转换为 SQL 方面非常有创意。
猜你喜欢
  • 2011-07-30
  • 2011-07-13
  • 1970-01-01
  • 2021-05-18
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多