El problema era un plan de consulta obsoleto o incorrecto para mi consulta.
Resolví el problema de eliminar los planes de consulta existentes para esta consulta.
Gracias a Vladimir Baranov por señalarme en sommarskog.se/query-plan-mysteries.html. Gracias también a tschmit007 y annemartijn.
Tuve que identificar los planes de consulta para mi consulta en la base de datos usando la siguiente consulta:
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%'
Esta es una versión ligeramente modificada de la consulta del artículo de sommarskog. Tenga en cuenta que debe poner su propio código en las declaraciones similares para encontrar su consulta. Esta consulta responde con la lista de atributos y el identificador del plan para cada plan de consulta de mi consulta.
Traté de averiguar qué plan procedía de SSMS y cuál de EF, así que los eliminé todos con la siguiente sintaxis:
dbcc freeproccache([your plan handle here])
El nuevo plan creado para mi consulta EF funcionó perfectamente. Aparentemente, el plan EF no tuvo en cuenta que recientemente había actualizado las estadísticas en la base de datos. Desafortunadamente, no sé cómo hacer sp_recompile para una consulta EF.