如何使用Dapper获取Grade实体中的Students嵌套列表?
获取包含Students列表的Grade结果解决方案
步骤1:编写关联SQL查询
通过LEFT JOIN关联Grade和Student表,确保能获取所有年级及其对应学生数据(包括无学生的年级):
SELECT g.GradeId, g.GradeName, g.Section, s.Id, s.Name, s.CurrentGradeId FROM Grade g LEFT JOIN Student s ON g.GradeId = s.CurrentGradeId
步骤2:用Dapper映射父子关系
Dapper返回平级查询结果,需通过字典缓存已创建的Grade实例,将同年级学生归集到对应Students集合:
using var connection = _context.CreateConnection(); var gradeCache = new Dictionary<int, Grade>(); var queryResult = await connection.QueryAsync<Grade, Student, Grade>( @"SELECT g.GradeId, g.GradeName, g.Section, s.Id, s.Name, s.CurrentGradeId FROM Grade g LEFT JOIN Student s ON g.GradeId = s.CurrentGradeId", (grade, student) => { // 缓存年级实例,避免重复创建 if (!gradeCache.TryGetValue(grade.GradeId, out var existingGrade)) { existingGrade = grade; existingGrade.Students = new List<Student>(); // 初始化集合,防止空引用 gradeCache.Add(existingGrade.GradeId, existingGrade); } // 将学生添加到对应年级的集合中 if (student != null) { existingGrade.Students.Add(student); student.CurrentGrade = existingGrade; // 可选:关联学生的CurrentGrade导航属性 } return existingGrade; }, splitOn: "Id" // 指定字段分割点:前半段映射Grade,后半段映射Student ); // 返回去重后的Grade列表 return gradeCache.Values.ToList();
关键说明
- 字典缓存:用
gradeCache跟踪已创建的Grade对象,避免同一年级被多次实例化。 - splitOn参数:必须对应SQL结果中
Student字段的起始列(此处为Id),确保Dapper正确区分Grade和Student的字段映射。 - LEFT JOIN:保证无学生的年级也会被返回,此时其
Students集合为空列表。 - 集合初始化:必须手动初始化
Grade.Students集合,否则会触发NullReferenceException。
内容的提问来源于stack exchange,提问作者Jitendra
相关产品推荐
相关产品推荐

