Il problema era un piano di query obsoleto o errato per la mia query.
Ho risolto il problema per l'eliminazione dei piani di query esistenti per questa query.
Grazie a Vladimir Baranov per avermi indicato sommarskog.se/query-plan-mysteries.html. Grazie anche a tschmit007 e annemartijn.
Ho dovuto identificare i piani di query per la mia query nel database utilizzando la seguente query:
SELECT qs.plan_handle, a.attrlist, est.dbid, text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) est
CROSS APPLY (SELECT epa.attribute + '=' + convert(nvarchar(127), epa.value) + ' '
FROM sys.dm_exec_plan_attributes(qs.plan_handle) epa
WHERE epa.is_cache_key = 1
ORDER BY epa.attribute
FOR XML PATH('')) AS a(attrlist)
WHERE est.text LIKE '%standardHourRate%' and est.text like '%q__7%'and est.text like '%Unit Overhead%'
AND est.text NOT LIKE '%sys.dm_exec_plan_attributes%'
Questa è una versione leggermente modificata della query dall'articolo di sommarskog. Nota che devi inserire il tuo codice nelle istruzioni simili per trovare la tua query. Questa query risponde con l'elenco degli attributi e l'handle del piano per ogni piano di query per la mia query.
Ho cercato di capire quale piano provenisse da SSMS e quale da EF, quindi li ho cancellati tutti, usando la seguente sintassi:
dbcc freeproccache([your plan handle here])
Il nuovo piano creato per la mia query EF ha funzionato perfettamente. Apparentemente, il piano EF non ha tenuto conto del fatto che avevo aggiornato le statistiche sul database di recente. Sfortunatamente, non so come eseguire una sp_recompile per una query EF.