首页 > 解决方案 > 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);

标签: ef-core-2.0ef-core-3.0

解决方案


您的代码中有几个设计缺陷被 EF 核心 2 扫到了地毯下。

  1. 您的存储库不共享一个上下文实例。EF core 2 也无法从您的代码中创建一个 SQL 查询,但它默默地切换到客户端评估。也就是说,它只执行了两个 SQL 查询并将它们连接到内存中。这一定是非常低效的。EF 核心 3 中最好的设计决策之一是放弃自动客户端评估,所以现在您遇到了这个错误。

  2. 您不使用导航属性。使用像 EF 这样的 ORM,几乎不需要使用手动连接。该类Instructor应具有类似的导航属性CoursesCourse类似的导航属性Instructor

  3. 无论如何不要使用这个冗余的存储库层。正如您已经在这段小代码中体验到的那样,它通常会使事情变得比必要的更难,而且没有任何附加价值。


推荐阅读