Несколько вопросов. Вы можете разделить запрос, чтобы разбить результаты, но область действия вашего DbContext должна быть в самой внешней точке цепочки, а не внутри самой внутренней:
Это здесь:
static IQueryable<T> Query<T>(Func<IQueryable<ServicesData>, IQueryable<T>> f, string path1 = null, string path2 = null, string path3 = null, string path4 = null, string path5 = null) {
try {
using (var dbc = new MyDbContext() ) { // DbContext should not be scoped here...
var res = dbc.ServicesData
Как самый простой рефакторинг:
static IQueryable<T> Query<T>(MyDbContext dbc, Func<IQueryable<ServicesData>, IQueryable<T>> f, string path1 = null, string path2 = null, string path3 = null, string path4 = null, string path5 = null) {
try
{
var res = dbc.ServicesData.AsQueryable();
if(path1 != null)
if(path1.Contains("%") || path1.Contains("_"))
res = res.Where(EF.Functions.Like(sd.Path1, path1));
else
res = res.Where(sd.Path1 == path1);
// Repeat for Path 2 - 5 ....
return f(res);
}
catch (Exception ex_)
{
return VList<T>.Empty.AsQueryable();
}
}
Сначала мы передаем DbContext. Если контекст ограничен здесь, список должен быть материализован перед возвращением. Цель состоит в том, чтобы позволить вызывающим абонентам еще больше уменьшить выражение перед выполнением списка. Это означает, что DbContext должен быть ограничен за пределами этого начального поколения и передан. С контейнерами IoC, управляющими областью действия времени жизни, вы можете обойти это, если DbContext внедрен и ограничен областью запроса или общей области времени жизни.
Следующее предложение по улучшению состоит в том, чтобы переместить условные проверки параметров из Linq в обычные условия, чтобы проверка «Подобно / равно» была добавлена, только если было предоставлено условие. Это приведет к более простому и быстрому запуску SQL на сервере.
Таким образом, конечный результат будет выглядеть примерно так:
using (var dbContext = new MyDbContext())
{
var lastHourProcessTime = Query(dbContext, Int1InLastHour, "Publisher", "%", "ItemProcessTime").Sum();
}
Я понимаю, что вы пытаетесь перейти сюда, но абстрагирование выражений от EF неизбежно приведет к запутанному коду и все еще подвержено ограничениям и ошибкам. ИМО, упрощая его, как правило, приводит к меньшему количеству проблем, но давайте посмотрим, приблизит ли это вас.