我有這個查詢在幕後使用LinqToEntities。有沒有一種有效的方式來進行中間計算Linq to Entities
(...)
.GroupBy(x => x.FahrerID)
.Select(x => new FahrerligaEintrag()
{
FahrerID = x.Key,
FahrerFullName = string.Empty,
VollgasKmAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * (x.Sum(y => y.Gas100ProzentInMeter.Value) + x.Sum(y => y.Gas90ProzentInMeter.Value)),
LeerlaufInProzent = (100m/x.Sum(y => y.BasisSekunden)) * x.Sum(y => y.LeerlaufInSekunden.Value),
VerbrauchLiterAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * x.Sum(y => y.VerbrauchInLiter.Value) * 1000,
RollenKmAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * x.Sum(y => y.RollenInMeter.Value),
TempomatKmAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * x.Sum(y => y.TempomatInMeter.Value),
GeschwindigkeitsuebertretungenAnzahlAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * 1000 * x.Sum(y => y.UebertretungenAnzahl.Value),
GangwechselAnzahlAufHundertKm = (100m/x.Sum(y => y.BasisMeter)) * 1000 * x.Sum(y => y.GangwechselAnzahl.Value)
});
正如你可以看到這部分重複幾次(100米/ x.Sum(Y => y.BasisMeter))。
在Linq to Objects中,感覺自然是首先投影到匿名類中來計算因子,以避免重複計算。像這樣:
.GroupBy(x => x.FahrerID)
.Select(x => new
{
Grouping = x,
BasisMeterFaktor = 100m/x.Sum(y => y.BasisMeter),
BasisSekundenFaktor = 100m /x.Sum(y => y.BasisSekunden)
})
.Select(x => new FahrerligaEintrag()
{
FahrerID = x.Grouping.Key,
FahrerFullName = string.Empty,
VollgasKmAufHundertKm = x.BasisMeterFaktor * (x.Grouping.Sum(y => y.Gas100ProzentInMeter.Value) + x.Grouping.Sum(y => y.Gas90ProzentInMeter.Value)),
LeerlaufInProzent = x.BasisSekundenFaktor * x.Grouping.Sum(y => y.LeerlaufInSekunden.Value),
VerbrauchLiterAufHundertKm = x.BasisMeterFaktor * x.Grouping.Sum(y => y.VerbrauchInLiter.Value) * 1000,
RollenKmAufHundertKm = x.BasisMeterFaktor * x.Grouping.Sum(y => y.RollenInMeter.Value),
TempomatKmAufHundertKm = x.BasisMeterFaktor * x.Grouping.Sum(y => y.TempomatInMeter.Value),
GeschwindigkeitsuebertretungenAnzahlAufHundertKm = x.BasisMeterFaktor * 1000 * x.Grouping.Sum(y => y.UebertretungenAnzahl.Value),
GangwechselAnzahlAufHundertKm = x.BasisMeterFaktor * 1000 * x.Grouping.Sum(y => y.GangwechselAnzahl.Value)
});
但是,在LinqToEntities中,這導致表現不佳的SQL代碼。至少在我使用的這個Oracle後端(以及我無法配置的實際向我顯示SQL的情況下)。所以,我想知道是否有另一種方法來避免重複計算,或者如果這只是我能得到的最快速度。
打擾所有這些德語變量名稱。我相信你仍然有意義。
UPDATE
我能夠使用ToTraceString()的建議。有趣的是,在投影中,SQL包含18個(!!!)SELECT語句。沒有它,它只包含2個。
感謝您的回答。 「讓」只是查詢語法糖,並轉換爲Select()投影。編譯器根本不知道查詢語法。這一切都歸結爲編譯器級別的擴展方法。不過,我可以按照你的建議使用ToTraceString()。我不知道,我在幾個月前試圖使用它,但沒有運氣,但現在它可能會工作,因爲底層devart oracle驅動程序的更新。 SQL看起來很糟糕,但我試圖進一步調查。很遺憾,我無法在此發佈。 – Christoph
我更新了問題。事實證明,隨着投影的實施,SQL變得越來越複雜。不知道在一個查詢中是否有另一種解決方法。 – Christoph
@Christoph我看不出去除投影會如何將SELECT的數量減少到2,因爲每個.Sum()都需要一個。把每個.Sum()調用放到投影中怎麼樣?我認爲你不會從中獲得太多的表現,但至少可以更清楚地瞭解所有涉及的屬性。我已經計算了10個.Sum(),儘管如此。 –