实体框架查询失踪的SQL Server 2012

问题描述:

上筛选的索引我有这样的EF查询:(只保留必要的一部分)实体框架查询失踪的SQL Server 2012

int maxRetryCount = 5; 
var erroredArchiveFilesQuery = 
    transitionLogSessionContext.Set<ArchivedFile>().Where(f => 
    f.RetryCount < maxRetryCount 
).Take(maxBatchSize); 

它错过可用过滤索引。

除去可变maxRetryCount当这样

var erroredArchiveFilesQuery = 
transitionLogSessionContext.Set<ArchivedFile>().Where(f => 
f.RetryCount < 5 && 
).Take(maxBatchSize); 

将使用筛选索引鉴于。

从第一EF查询的实际SQL ...

SELECT TOP (500) 
    [Extent1].[Id] AS [Id], 
    .. 
FROM 
    [ArchivedFile] AS [Extent1] 
WHERE 
    ([Extent1].[RetryCount] < @p__linq__0) 

过滤索引包含列RetryCount和过滤器“RetryCount重< 5”

我怎样才能使一个EF查询与变量会击中筛选索引?

我假设问题出在EF语句正在准备中,因此可以重复使用,这会使SQL Server混淆不清。

+0

你应该澄清你的代码。你的代码无效(不编译)。另外请确保您将所有代码部分标记为代码。 – Mat

+0

我有问题得到中间代码部分显示为代码,但重写它有帮助。我不打算让代码能够编译,但希望所有的基本部分都在那里。如果问题现在没有意义,请让我知道我应该在哪里清理。谢谢 –

+0

。这里(f => f.RetryCount Mat

您需要确保SQL Server每次都基于参数maxRetryCount的实际值重新编译计划。这在EF中并不容易,但可以使用自定义数据库拦截器将option (recompile)提示添加到您的查询中。

看到这里SimpleTalk Article

public class RecompileDbCommandInterceptor : IDbCommandInterceptor 
{ 
    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 
    { 
     if(!command.CommandText.EndsWith(" option(recompile)")) 
     { 
      command.CommandText += " option(recompile)"; 
     } 
    } 
} 

详细信息您可以使用它像这样:

var interceptor = new RecompileDbCommandInterceptor(); 
DbInterception.Add(interceptor); 

int maxRetryCount = 5; 
var erroredArchiveFilesQuery = 
    transitionLogSessionContext.Set<ArchivedFile>().Where(f => 
    f.RetryCount < maxRetryCount 
).Take(maxBatchSize); 

DbInterception.Remove(interceptor); 

注意,这种拦截是全局启用,而不是上下文的具体实例,所以你可能想再次禁用它,以便其他查询不受影响。