简体   繁体   English

实体框架查询未命中过滤索引WHERE BIT字段= 0

[英]Entity Framework queries miss filtered index WHERE BIT field = 0

I've noticed that Entity Framework translates LINQ queries with negative boolean filters such that the generated query plan won't use a filtered index. 我注意到Entity Framework使用负布尔过滤器转换LINQ查询,这样生成的查询计划就不会使用过滤索引。 For example, the query: 例如,查询:

context.Foo.Count(f => !f.IsActive)

generates the SQL statement: 生成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]

Notice the WHERE clause uses [IsActive] <> cast(1 as bit) , rather than the more intuitive [IsActive] = 0 . 注意WHERE子句使用[IsActive] <> cast(1 as bit) ,而不是更直观的[IsActive] = 0 This becomes an issue when using filtered indexes. 使用筛选索引时,这会成为问题。 The plan for the above query will not use the following index: 上述查询的计划不会使用以下索引:

CREATE INDEX IX_Foo_IsActive ON Foos (IsActive) WHERE (IsActive = 0)

I suspect the reason that EF generates queries this way has something to do with DB null semantics, but this happens even with non-nullable bit fields. 我怀疑EF以这种方式生成查询的原因与DB null语义有关,但即使使用不可空的位字段也会发生这种情况。 I've verified that writing the filtered index with EF's syntax ( IsActive <> 1 ) fixes the issue, but that would break any non-EF queries using the more common syntax. 我已经验证用EF的语法( IsActive <> 1 )编写过滤的索引可以解决问题,但是这会破坏使用更常见语法的任何非EF查询。

Is there a better work around? 有更好的解决方法吗?

Full example program here: http://dotnetfiddle.net/3kZugt . 这里有完整的示例程序: http//dotnetfiddle.net/3kZugt The entity type used above is: 上面使用的实体类型是:

public class Foo
{
    public int Id { get; set; }
    public bool IsActive { get; set; }
}

It's not unusual that for some strange reason, sometimes we don't see something which is really obvious: do a direct translation of your DB predicate to a C# predicate, ie 出于某种奇怪的原因,有时候我们看不到一些非常明显的东西并不常见:将数据库谓词直接转换为C#谓词,即

WHERE IsActive = 0

is translated to 被翻译成

f => f.IsActive = false

You have to stop thinking in C# and start thinking in SQL ;) 你必须停止在C#中思考并开始在SQL中思考;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM