0

上篩選的索引我有這樣的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 <5 &&) 這段代碼應該做什麼? – Mat

回答

0

您需要確保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); 

注意,這種攔截是全局啓用,而不是上下文的具體實例,所以你可能想再次禁用它,以便其他查詢不受影響。