如何将含IN子句与内连接的SQL查询转为LINQ to Entities查询
修正你的LINQ to Entities查询以匹配原SQL逻辑
先明确你原SQL的核心逻辑:筛选出关联的Objetivo的ProcessoID等于传入参数的AvaliacaoImpacto记录,同时关联所需的关联表,还要计算三个影响分数的平均值。
你当前的LINQ查询问题出在Where条件写反了——现在的逻辑是“检查是否存在任意一条Objetivo的ProcessoID等于参数”,这会导致所有AvaliacaoImpacto记录都被返回,完全没起到筛选目标数据的作用。
修正后的完整LINQ查询
var targetProcessoId = planoRiscos.Auditoria.ProcessoID; var queryImpactos = await _context.AvaliacaoImpacto // 精准匹配原SQL的WHERE子查询逻辑:关联的Objetivo的ProcessoID等于目标值 .Where(ai => ai.Objetivo.ProcessoID == targetProcessoId) // 包含需要关联的所有实体(对应原SQL的INNER JOIN) .Include(ai => ai.Evento) .Include(ai => ai.Objetivo) .Include(ai => ai.ImpactoFinanceiro) .Include(ai => ai.ImpactoMissao) .Include(ai => ai.ImpactoReputacao) // 投影出原SQL的所有字段,包括计算平均分 .Select(ai => new { ObjetivoId = ai.Objetivo.PK_OBJETIVO, // 对应原SQL的ob.PK_OBJETIVO EventoNome = ai.Evento.NM_EVENTO, // 对应原SQL的ev.NM_EVENTO NotaFinanceiro = ai.ImpactoFinanceiro.QT_NOTA_IMPACTO, NotaMissao = ai.ImpactoMissao.QT_NOTA_IMPACTO, NotaReputacao = ai.ImpactoReputacao.QT_NOTA_IMPACTO, Media = (ai.ImpactoFinanceiro.QT_NOTA_IMPACTO + ai.ImpactoMissao.QT_NOTA_IMPACTO + ai.ImpactoReputacao.QT_NOTA_IMPACTO) / 3.0 }) .ToListAsync();
关键细节说明
- 筛选条件修正:原SQL的子查询等价于直接检查
AvaliacaoImpacto关联的Objetivo的ProcessoID是否等于目标值,EF会自动处理外键关联,生成和原SQL一致的WHERE逻辑。 - 平均分计算:注意用
3.0而非3,避免整数除法导致小数部分丢失,保证结果和原SQL的Media字段一致。 - 实体属性适配:如果你的实体类属性名和数据库列名不一致(比如用C#驼峰命名),请对应调整代码中的属性名称(例如把
PK_OBJETIVO改成PkObjetivo)。
如果你的实体类中AvaliacaoImpacto和Objetivo的关联是通过外键字段(比如FK_AVALIACAO_IMPACTO_OBJETIVO)而非导航属性直接访问,也可以用以下写法:
.Where(ai => _context.Objetivo.Any(o => o.PK_OBJETIVO == ai.FK_AVALIACAO_IMPACTO_OBJETIVO && o.FK_OBJETIVO_PROCESSO == targetProcessoId))
不过第一种直接访问导航属性的写法更简洁,EF也会自动优化成高效的SQL查询。
内容的提问来源于stack exchange,提问作者woshington rodrigues
相关产品推荐
相关产品推荐

