2016-03-01 67 views
1

有谁知道为什么这样的逻辑:LINQ增加额外的逻辑WHERE子句

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 

我希望它只会比较列是否为空或者它是否具有我通过的值。

喜欢的东西:

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

+1

看起来像一个EF自动生成的查询。它“尝试”优化 - 尝试成为关键词......我假设在这种情况下,它正在查看一个“可空”属性并进行相应的转换。 – sgeddes

+2

你真的读过每一个比较吗?它正在做你想做的,它只是更详细的。 – Ellesedil

+0

@Ellesedil感谢您的评论。我知道它确实有效......我只是在想如果有办法让它更清洁。 – Catinodeh

回答

3

您可以通过以下操作清理一点点:

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

注与regionid的类型更换Type

这将生成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,则返回值。在你的代码可以在null传递给.Equals功能,它应该返回值。

+0

这将抛出一个运行时错误'system.Type'必须是非空值类型,以便将其用作通用类型或方法'System.Nullable '中的参数'T',您可能需要或者您只需使用类型,如果这样你就应该对 –

+0

@ johnny5我把键入有更清楚,因为我不知道他使用的是什么呀 – drneel

+0

我想通了这一点以后它好像你正在使用类型的占位符,其如何将一个实例放在那里让我感到困惑,甚至会因为使用初始化列表而编译 –