LINQ为WHERE子句添加了额外的逻辑

时间:2016-03-01 18:08:07

标签: c# sql linq

有谁知道这个逻辑的原因:

var t = _repo.Surveys
             .Where(s => s.status && 
                         (s.regionid == null || s.regionid.Value.Equals(regionid)))
             .ToList();

会构造这个WHERE子句吗?

WHERE ([Extent1].[status] = 1) 
  AND (([Extent1].[regionid] IS NULL) OR 
       (([Extent1].[regionid] = @p__linq__0) AND ( NOT ([Extent1].[regionid] IS NULL OR @p__linq__0 IS NULL))) OR 
       (([Extent1].[regionid] IS NULL) AND (@p__linq__0 IS NULL)))'
,N'@p__linq__0 int',@p__linq__0=0

我希望它只会比较列是否为null或者是否具有我传递的值。

类似的东西:

例如

WHERE status = 1 AND (regionid IS NULL OR regionid = 0),

1 个答案:

答案 0 :(得分:3)

您可以通过执行以下操作来清理它:

var parameters = new List<Type?>() { null, regionid };
var t = _repo.Surveys
             .Where(s => s.status && parameters.Contains(s.regionid))
             .ToList();

注意将Type替换为regionid的类型。

这将生成类似于:

的SQL
WHERE (0 = [Extent1].[Status]) 
  AND ((([Extent1].[RegionId] IN (regionIdValue)) AND ([Extent1].[RegionId] IS NOT NULL)) OR 
       ([Extent1].[RegionId] IS NULL))

此时唯一的额外 SQL是AND ([Extent1].[RegionId] IS NOT NULL)条件,作为IN的一部分。

话虽如此,原始LINQ生成的SQL完全有道理。 (NOT ([Extent1].[RegionId] IS NULL OR @p__linq__0 IS NULL))条件排除数据库值为null或参数值为NULL的实例。

然后(([Extent1].[regionid] IS NULL) AND (@p__linq__0 IS NULL))条件实际上是有效的,因为它返回值,其中数据库值和参数为空。在您的代码中,您可以将null传递给.Equals函数,它应该返回该值。