首页 > 解决方案 > 任何改进此 EF 查询的方法

问题描述

在第三方使用的 WebApi 中,今天我们开始在他们调用方法时遇到故障。

该方法连接到几个表并将它们连接起来。来自 EF 的错误消息是

查询处理器用尽了内部资源,无法生成查询计划。这是一个罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。请简化查询。如果您认为您错误地收到了此消息,请联系客户支持服务以获取更多信息。

return context.leads
            .Where(q => q.eventID == 1234)
            .Join(context.config,
                leads => leads.configId,
                config => config.configId,
                (leads, config) => new { leads, config })
            .Where(p => keys.Contains(p.leads.leadId))

keys 是检索到的潜在客户 ID 的 IEnumerable。基本上,我们提取 id 列表,然后执行上述操作,检查键集合,以便我们的查询返回准确的数据。

密钥拥有大约 28k 个 ID。

请注意,自从迁移到 Azure 云后,这才开始成为一个问题,但我认为这是一个巧合

标签: c#sql-serverentity-framework

解决方案


keys 是检索到的潜在客户 ID 的 IEnumerable。

密钥拥有大约 28k 个 ID。

所以这:

return context.leads
            .Where(q => q.eventID == 1234)
            .Join(context.config,
                leads => leads.configId,
                config => config.configId,
                (leads, config) => new { leads, config })
            .Where(p => keys.Contains(p.leads.leadId))

将 ID 粘贴到 SQL 查询文本中,例如:

SELECT … WHERE LeadId in (1,23,3,4,5,6,45,34, . . . )

导致大型、不可重用和昂贵的解析和编译查询。最好将 ID 加载到表中并加入它们,或者使用 XML、JSON 或表值参数将它们传递到服务器。

基本上我们提取 id 列表,然后我们执行上述操作

然后不要那样做。如果您想要的 ID 列表在数据库中,则将其加入您的查询中。避免从数据库中读取 28K ID,然后将它们发送回您的查询正文。


推荐阅读