EF CORE 3.0 не может использовать несколько экземпляров DbContext при выполнении одного запроса

После обновления.Net Core 2.2 до 3.0 приложения выдают это сообщение об ошибке.

Cannot use multiple DbContext instances within a single query execution

Какое обходное решение?

IQueryable<ApplicationUser> query;

var queryJoin = from ci in _courseInstructorRepository.Table
        join uc in _userCourseRepository.Table on ci.CourseId equals uc.CourseId
        select new { ci, uc };

if (userId > 0)
    queryJoin = queryJoin.Where(x => x.ci.UserId == userId);

if (courseId > 0)
    queryJoin = queryJoin.Where(x => x.uc.CourseId == courseId);

if (classId > 0)
    queryJoin = queryJoin.Where(x => x.uc.CourseClassId == classId);

query = queryJoin.Select(x => x.uc.User).Distinct();

if (!string.IsNullOrEmpty(studentFirstChar))
    query = query.Where(x => x.FirstName.StartsWith(studentFirstChar));

if (schoolId > 0)
    query = query.Where(x => x.SchoolId == schoolId);

query = query.OrderBy(x => x.UserName);

return new PagedList<ApplicationUser>(query, pageIndex, pageSize);

2 ответа

У вас есть пара конструктивных недостатков в вашем коде, которые EF core 2 заметила.

  1. Ваши репозитории не используют один экземпляр контекста. EF core 2 также не смог создать ни один SQL-запрос из вашего кода, но незаметно переключился на оценку на стороне клиента. То есть он просто выполнил два SQL-запроса и соединил их в памяти. Это должно было быть крайне неэффективным. Одним из лучших дизайнерских решений в EF core 3 был отказ от автоматической оценки на стороне клиента, поэтому теперь вы получаете эту ошибку.

  2. Вы не используете свойства навигации. При использовании ORM, такого как EF, вряд ли когда-либо понадобится ручное объединение. ВInstructor класс должен иметь свойство навигации, например Courses, а также Course свойство навигации, например Instructor.

  3. В любом случае не используйте этот избыточный уровень репозитория. Как вы уже заметили в этом небольшом фрагменте кода, он обычно усложняет задачу без какой-либо дополнительной ценности.

Одна из ваших переменных была создана с использованием другого экземпляра DBContext, поэтому, когда вы пытаетесь использовать ее как часть другого запроса DBContext, она выдает. Чтобы решить эту проблему, необходимо закрыть первый DBContext и вызвать DBContext.Attach(model) на втором.

Другие вопросы по тегам