使用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查询? 有什么建议可以解决这个问题吗?

谢谢!

试试这个:

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

使用

 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) 

哪个是正确的。

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

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

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

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