我使用Entity Framework(v6.1.1)执行以下LINQ查询:
private IList<Customer> GetFullCustomers(IEnumerable<int> customersIds)
{
IQueryable<Customer> fullCustomerQuery = GetFullQuery();
return fullCustomerQuery.Where(c => customersIds.Contains(c.Id)).ToList();
}
这个查询被翻译成相当不错的SQL:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName]
-- ...
FROM [dbo].[Customer] AS [Extent1]
WHERE [Extent1].[Id] IN (1, 2, 3, 5)
但是,我在查询编译阶段获得了非常显着的性能影响。呼叫:
ELinqQueryState.GetExecutionPlan(MergeOption? forMergeOption)
占用每个请求约50%的时间。深入研究,结果是每次我传递不同的customersIds时都会重新编译查询。根据MSDN article,这是一种预期的行为,因为在查询中使用的IEnumerable被认为是volatile,并且是缓存的SQL的一部分。这就是为什么SQL对于customersIds的每个不同组合都不同,它总是有不同的哈希值,用于从缓存中获取编译查询。
现在问题是:如何在仍然查询多个customersIds时避免重新编译?