使用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。