You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据库数据检索提速:LINQ查询简化方案及Dapper适用性咨询

LINQ查询优化与Dapper使用建议

简化LINQ查询方案

你的初始查询速度慢的核心原因是在Select内部调用.ToList()导致客户端评估,EF Core会先拉取所有关联数据到内存再处理,引发大量不必要的数据传输和计算。同时,错误的分组方式导致优化后的查询生成冗余子查询。以下是两种优化方案:

方案1:修正投影查询(推荐)

移除Courses和Lecturers中的.ToList(),让EF Core将整个查询翻译为单条SQL语句(包含必要的JOIN),避免N+1查询和客户端评估:

var userDtos = _context.Users
    .Select(user => new UserGetDto
    {
        Id = user.Id,
        Name = user.Name,
        SurName = user.SurName,
        Age = user.Age,
        Faculty = user.Faculty != null
            ? new FacultyOnlyDto
            {
                Id = user.Faculty.Id,
                FacultyName = user.Faculty.FacultyName
            }
            : null,
        Courses = user.UsersCourses
            .Where(uc => uc.Course != null)
            .Select(uc => new CourseOnlyDto
            {
                Id = uc.Course.Id,
                CourseName = uc.Course.CourseName
            }),
        Lecturers = user.UsersLecturers
            .Where(ul => ul.Lecturer != null)
            .Select(ul => new LecturerOnlyDto
            {
                Id = ul.Lecturer.Id,
                Name = ul.Lecturer.Name,
                SurName = ul.Lecturer.SurName,
                Age = ul.Lecturer.Age
            })
    })
    .ToList();

方案2:显式预加载关联数据

如果需要更直观的控制关联数据加载,可以使用Include和ThenInclude预加载,再投影到DTO:

var userDtos = _context.Users
    .Include(u => u.Faculty)
    .Include(u => u.UsersCourses)
        .ThenInclude(uc => uc.Course)
    .Include(u => u.UsersLecturers)
        .ThenInclude(ul => ul.Lecturer)
    .Select(user => new UserGetDto
    {
        Id = user.Id,
        Name = user.Name,
        SurName = user.SurName,
        Age = user.Age,
        Faculty = user.Faculty != null
            ? new FacultyOnlyDto
            {
                Id = user.Faculty.Id,
                FacultyName = user.Faculty.FacultyName
            }
            : null,
        Courses = user.UsersCourses
            .Where(uc => uc.Course != null)
            .Select(uc => new CourseOnlyDto
            {
                Id = uc.Course.Id,
                CourseName = uc.Course.CourseName
            }).ToList(),
        Lecturers = user.UsersLecturers
            .Where(ul => ul.Lecturer != null)
            .Select(ul => new LecturerOnlyDto
            {
                Id = ul.Lecturer.Id,
                Name = ul.Lecturer.Name,
                SurName = ul.Lecturer.SurName,
                Age = ul.Lecturer.Age
            }).ToList()
    })
    .ToList();

数据库层面优化

除了代码调整,确保数据库存在以下索引:

  • UsersCourses表的UserId字段索引
  • UsersLecturers表的UserId字段索引
  • Users表的FacultyId字段索引
    这些索引能大幅提升JOIN操作的效率。

是否需要改用Dapper?

  • 如果上述EF Core优化后性能仍未达标,Dapper是可行的选择。Dapper允许你编写原生SQL,对复杂查询的执行计划控制更精细,通常在大数据量或复杂关联场景下性能优于EF Core。
  • 但如果EF Core优化后已满足性能要求,无需切换——EF Core提供的强类型检查、LINQ的可读性和维护性更有优势。

内容的提问来源于stack exchange,提问作者Nika Kiknadze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:32:05