[英]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.