![](/img/trans.png)
[英]Invalid column name when including child collection navigation property involving 2 joins to the same table
[英]Duplicated joins in Npgsql for the same navigation property
这个问题已经存在在这里 ,但对于实体框架TSQL
当对一个选择多次使用相同的导航属性时,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以优化重复连接?
如果没有,哪个选项最适合解决此问题?
确实,这是Entity Framework的问题,但是我找到了一种解决方法,希望这对某人有所帮助。
这是原来where
的LINQ查询的一部分:
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,
}
请注意where的最后一个条件,该条件对cr
的所有子实体求和,如果我们取出该最后一个条件,则所有重复的LEFT OUTTER JOIN
都将被一个JOIN
替换,出于某种原因,Entity Framework不会如查询的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语句进行过滤,而是将汇总结果存储为投影的一部分,然后将第二个where应用于结果查询。
这将导致查询速度大大提高,只对翻译后的SQL语句进行必要的联接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.