我有一个查询,它使用LinqToEntities在后台运行。
(...)
.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)
});
正如您所看到的,这部分内容被重复多次(100m / 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)。因此,我想知道是否还有其他方法可以避免重复计算,或者这是我能得到的最快的方法。
请原谅所有那些德国变量名。我相信您仍然可以理解其含义。
更新
我能够使用建议的ToTraceString()。有趣的是,在投影方面,SQL包含18(!!!)SELECT语句。如果没有它,它只包含2个。