У меня есть этот запрос, который использует 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)
});
Как вы можете видеть, эта часть повторяется несколько раз (100 м / х.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.