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 заметила.
Ваши репозитории не используют один экземпляр контекста. EF core 2 также не смог создать ни один SQL-запрос из вашего кода, но незаметно переключился на оценку на стороне клиента. То есть он просто выполнил два SQL-запроса и соединил их в памяти. Это должно было быть крайне неэффективным. Одним из лучших дизайнерских решений в EF core 3 был отказ от автоматической оценки на стороне клиента, поэтому теперь вы получаете эту ошибку.
Вы не используете свойства навигации. При использовании ORM, такого как EF, вряд ли когда-либо понадобится ручное объединение. В
Instructor
класс должен иметь свойство навигации, напримерCourses
, а такжеCourse
свойство навигации, напримерInstructor
.В любом случае не используйте этот избыточный уровень репозитория. Как вы уже заметили в этом небольшом фрагменте кода, он обычно усложняет задачу без какой-либо дополнительной ценности.
Одна из ваших переменных была создана с использованием другого экземпляра DBContext, поэтому, когда вы пытаетесь использовать ее как часть другого запроса DBContext, она выдает. Чтобы решить эту проблему, необходимо закрыть первый DBContext и вызвать DBContext.Attach(model) на втором.