问题 使用LINQ-to-SQL处理where子句中的空值


Visual Studio中的LINQ-to-SQL查询生成带有错误的SQL查询。在LINQPad中,使用相同数据库(或DataContext)的相同LINQ查询运行得很好。

LINQ查询

var accesDomaines = from t in db.Access
                  where t.IdUser == access.IdUtilisateur
                  where t.IdDomain != null
                  where t.IdRole == access.IdRole
                  where t.IdPlace == access.IdPlace
                  select t;

以下是生成SQL的一小部分,其中发生错误:

WHERE (...) AND ([t3].[IdRole] = ) AND (...)

在where子句中等于之后,几乎没有任何东西!在LINQPad的SQL查询中,我们看到了好的where子句:

WHERE (...) AND ([t3].[IdRole] IS NULL) AND (...)

当我逐行比较来自VS和LINQPad的两个生成的SQL查询时,这是同样的事情。除了LINQPad使用params以及Visual Studio的where子句中缺少的右侧部分,如前所示。


注1

在LINQ查询中,我在where子句中尝试了这种语法:

where t.IdRole.Equals(acces.IdRole.Value)

但也会产生不好的结果。我甚至在LINQ查询之前尝试过类似的东西:

if (!acces.IdRole.HasValue) { acces.IdRole = null; }

笔记2

属性是可以为空的整数。如果property为null,我确实想在查询中使用null。显然,如果有价值,我想要财产的价值。

注3

我试过这个问题提出的主张: Linq where column ==(null reference)与column == null不同

......没有成功


有两个类似的LINQ查询的解释,但生成一个好的和一个坏的SQL查询?有什么建议可以解决这个问题吗?

谢谢!


5405
2018-03-09 19:23


起源



答案:


尝试这个:

where object.Equals(t.IdRole, access.IdRole)

10
2018-03-09 19:33



这很有效!但我仍然不明白为什么Visual Studio不会生成与LINQPad完全相同的SQL查询... LINQPad以不同的方式管理空值/引用?无论如何,谢谢。 - elbaid


答案:


尝试这个:

where object.Equals(t.IdRole, access.IdRole)

10
2018-03-09 19:33



这很有效!但我仍然不明白为什么Visual Studio不会生成与LINQPad完全相同的SQL查询... LINQPad以不同的方式管理空值/引用?无论如何,谢谢。 - elbaid


使用

object.Equals()

.Net将负责为null条件生成正确的sql。

例:

假设您有一个包含Suffix和Prefix等列的街道表。然后跟随linq查询不起作用:

  string suffix = "ST";
  string prefix = null;

  var map = from s in Streets
            where s.Suffix==suffix || s.Prefix==prefix
            select s;

它会生成以下sql:

SELECT [t0].[StreetId], [t0].[Prefix], [t0].[Suffix]
FROM [Street] AS [t0]
WHERE ([t0].[Suffix] = @p0) AND ([t0].[Prefix] = @p1)

我们可以清楚地看到它不会返回任何结果。

使用object.Equals():

  string suffix = "ST";
  string prefix = null;

  var map = from s in Streets
  where object.Equals(s.Suffix, suffix) && object.Equals(s.Prefix,prefix)
  select s;

会生成sql:

SELECT [t0].[StreetId], [t0].[Prefix], [t0].[Suffix]
FROM [Street] AS [t0]
WHERE ([t0].[Suffix] IS NOT NULL) AND ([t0].[Suffix] = @p0) 
         AND ([t0].[Prefix] IS NULL)

哪个是正确的。

(虽然迟到了,但希望扩大答案以造福他人)


5
2018-03-27 14:31





您是否尝试过验证您的属性是否具有Nullables提供的HasValues属性的值?

where t.IdRole == access.IdRole.HasValues ? access.IdRole.Value : null

也许这可行。我没有真正使用过LINQ-to-SQL。


0
2018-03-09 19:28