实体框架查询失踪的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混淆不清。
答
您需要确保SQL Server每次都基于参数maxRetryCount
的实际值重新编译计划。这在EF中并不容易,但可以使用自定义数据库拦截器将option (recompile)
提示添加到您的查询中。
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);
注意,这种拦截是全局启用,而不是上下文的具体实例,所以你可能想再次禁用它,以便其他查询不受影响。
你应该澄清你的代码。你的代码无效(不编译)。另外请确保您将所有代码部分标记为代码。 – Mat
我有问题得到中间代码部分显示为代码,但重写它有帮助。我不打算让代码能够编译,但希望所有的基本部分都在那里。如果问题现在没有意义,请让我知道我应该在哪里清理。谢谢 –
。这里(f => f.RetryCount Mat