Предположим, у нас есть сущность под названием FactValue. Эта сущность связана с сущностью KPI, и это отношение составляет 1 к 1 (каждый FactValue имеет KPI), и каждый KPI имеет отношение с сущностью Measure, и это отношение 1 к n. Итак, для каждого FactValue у нас есть один KPI и n показателей.
Я разработал панель для конечного пользователя, чтобы он мог писать свои собственные выражения в нашей базе данных, и я выполню это выражение с помощью DynamicExpressions. Если мы запустим простой запрос выбора, например:
FactValue.KPI.Measure.Average(it.MinimumValue)
он будет обслуживаться с итеративным подходом (для каждого кортежа FactValue-KPI он будет выполнять SQL-запрос для получения среднего минимальных значений мер). Но, очевидно, это можно сделать с помощью одного запроса, например:
select FactValue.FactValueId, avg(MinimumValue)
from FactValue
inner join KPI on FactValue.KPIId = KPI.KPIId
inner join Measure on KPI.MeasureId = Measure.MeasureId
group by FactValueId
Я тоже проверил это с помощью простого запроса Linq (примерно так):
var result = context.FactValue.KPI.Measure.Average(t=>t.MinimumValue)
Но когда я наблюдал за Profiler, было то же самое.
Учтите, что я не могу изменить способ создания выражения, потому что он зависит от конечного пользователя, и я не могу его контролировать. Так как я могу справиться с этим?
Я разработал на EF Core.
Попробуйте выполнить обновление до последней версии EF Core (в настоящее время 2.1.2). В общем, вы привязаны к переводчику запросов EF Core, который все еще далек от совершенства. Единственное, что вы можете сделать (особенно если у вас нет контроля над запросами), - это принять неэффективную реализацию и дождаться ее улучшения путем мониторинга и обновления до более новых выпусков EF Core.
Я так думаю, будем ждать и надеяться.


Я думаю, вам следует использовать другой подход. Взгляните на примеры linq http://linq101.nilzorblog.com/aggregate-operators.php#min-grouped
например. var category = context.FactValue.GroupBy (fv => fv.FactValueId) .Select (t => new {FactValueId = t.FactValueId, AverageMeasurement = t.Min (p => p.KPI.Measurement.MinimumValue)});
Я не проверял вышеизложенное.
Так же, как не этот запрос выполняет группировку по всей таблице FactValue, так что по прошествии времени и при росте таблицы производительность будет ухудшаться. Даже если вы настраиваете базу данных с помощью индексов и т. Д ...
Также в одном запросе вы используете "Среднее", а в другом "Мин."
Надеюсь это поможет
Спасибо, метод Min был моей ошибкой, и я исправил его. Как я уже сказал, я не могу изменить способ запроса, потому что на самом деле я не пишу запросы, а конечный пользователь будет писать их с помощью некоторых выражений.
Что это за EF? EF Core? Я спрашиваю, потому что EF6 всегда выполняет один SQL-запрос для каждого запроса LINQ.