此问题已存在here,但对于TSQ的实体框架
在select上多次使用相同的导航属性时,Npgsql查询会产生多个连接,每次使用一个导航属性。这导致了糟糕的性能损失(测试)
我已经读过这是EF 4的一个问题,但这个问题也发生在EF 6上。
我认为这是Npgsql LINQ to SQL转换器的问题
这是Npgsql为多次使用的相同导航属性生成的代码,显然,只需要一个连接(从其他问题复制,因为情况完全相同)
LEFT OUTER JOIN [dbo].[Versions] AS [Extent4] ON [Extent1].[IDVersionReported] = [Extent4].[ID]
LEFT OUTER JOIN [dbo].[Versions] AS [Extent5] ON [Extent1].[IDVersionReported] = [Extent5].[ID]
LEFT OUTER JOIN [dbo].[Versions] AS [Extent6] ON [Extent1].[IDVersionReported] = [Extent6].[ID]
LEFT OUTER JOIN [dbo].[Versions] AS [Extent7] ON [Extent1].[IDVersionReported] = [Extent7].[ID]
调整PostgreSql以优化重复连接是否可行?
如果没有,哪个选项最适合解决这个问题?
答案 0 :(得分:0)
事实上,这是实体框架的问题,但我找到了一种解决方法,希望这有助于某人。
这是LINQ查询的原始.hidden-xs or .visible-xs
部分:
where
注意where的最后一个条件,该条件执行 from cr in Creditos
where cr.validado == 1 &&
cr.fecharegistro >= Desde &&
cr.fecharegistro <= Hasta &&
!ProductosExcluidos.Contains(cr.idproducto.Value) &&
cr.amortizaciones.Sum(am => am.importecapital - am.pagoscap - am.capcancel) > 1
//All references to the navigation property cr.numcliente
//results on a separated LEFT OUTTER JOIN between this the 'creditos' and 'clientes' tables
select new ArchivoCliente
{
RFC = cr.numcliente.rfc,
Nombres = cr.numcliente.nombres,
ApellidoPaterno = cr.numcliente.apellidopaterno,
ApellidoMaterno = cr.numcliente.apellidomaterno,
}
的所有子实体的总和,如果我们取出最后一个条件,则所有重复的cr
都被一个LEFT OUTTER JOIN
替换JOIN
1}},由于某种原因,实体框架不喜欢查询where
部分的子查询或聚合
如果我们用其他等效查询替换原始查询,则只生成一个LEFT OUTTER JOIN
。
(from cr in Creditos
where cr.validado == 1 &&
cr.fecharegistro >= Desde &&
cr.fecharegistro <= Hasta &&
!ProductosExcluidos.Contains(cr.idproducto.Value) &&
//Excluded aggregate function condition from the first where
//the value is now on the select and used for posterior filtering
select new ArchivoCliente
{
RFC = cr.numcliente.rfc,
Nombres = cr.numcliente.nombres,
ApellidoPaterno = cr.numcliente.apellidopaterno,
ApellidoMaterno = cr.numcliente.apellidomaterno,
SumaAmort = cr.amortizaciones.Sum(am => am.importecapital - am.pagoscap - am.capcancel)
}).Where (x => x.SumaAmort > 1);
现在,不是直接过滤第一个where语句,而是将聚合结果存储为投影的一部分,然后将第二个应用于生成的查询。
这样可以实现更快的查询,只需要对已翻译的SQL语句进行必要的连接。