[英]Entity Framework queries miss filtered index WHERE BIT field = 0
我注意到Entity Framework使用负布尔过滤器转换LINQ查询,这样生成的查询计划就不会使用过滤索引。 例如,查询:
context.Foo.Count(f => !f.IsActive)
生成SQL语句:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Foos] AS [Extent1]
WHERE [Extent1].[IsActive] <> cast(1 as bit)
) AS [GroupBy1]
注意WHERE
子句使用[IsActive] <> cast(1 as bit)
,而不是更直观的[IsActive] = 0
。 使用筛选索引时,这会成为问题。 上述查询的计划不会使用以下索引:
CREATE INDEX IX_Foo_IsActive ON Foos (IsActive) WHERE (IsActive = 0)
我怀疑EF以这种方式生成查询的原因与DB null语义有关,但即使使用不可空的位字段也会发生这种情况。 我已经验证用EF的语法( IsActive <> 1
)编写过滤的索引可以解决问题,但是这会破坏使用更常见语法的任何非EF查询。
有更好的解决方法吗?
这里有完整的示例程序: http : //dotnetfiddle.net/3kZugt 。 上面使用的实体类型是:
public class Foo
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
出于某种奇怪的原因,有时候我们看不到一些非常明显的东西并不常见:将数据库谓词直接转换为C#谓词,即
WHERE IsActive = 0
被翻译成
f => f.IsActive = false
你必须停止在C#中思考并开始在SQL中思考;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.