如何将聚合函数结果与OOP实体类映射?以学生学期统计为例
问题与解决方案
问题描述
我设计了如下Student类:
public class Student { int id; string name; string section; int semester; }
需要统计并展示每个学期的学生人数(比如学期1有20名学生、学期2有40名学生),数据库中可通过以下聚合查询获取结果:
SELECT semester, COUNT(*) AS student_count FROM Students GROUP BY semester;
但Student类没有totalStudentInSemester属性,且添加该属性不合逻辑,当前使用ADO.NET,后续可能切换到EF Core,不清楚如何将聚合结果与类映射,或如何返回带详情的数据库结果。
解决方案
不需要修改Student类,应该创建**专用的统计DTO(数据传输对象)**来承载聚合查询结果——聚合统计数据和学生实体的职责完全分离,这样既符合单一职责原则,也能适配ADO.NET和EF Core两种场景。
1. 定义统计DTO
先创建一个专门用于存储学期学生数的类:
public class SemesterStudentCount { public int Semester { get; set; } public int StudentCount { get; set; } }
2. ADO.NET 实现映射
使用ADO.NET读取查询结果时,直接将数据映射到SemesterStudentCount即可:
List<SemesterStudentCount> semesterCounts = new List<SemesterStudentCount>(); // 假设已建立数据库连接 using (SqlConnection connection = new SqlConnection("你的连接字符串")) { string query = @"SELECT semester, COUNT(*) AS student_count FROM Students GROUP BY semester;"; using (SqlCommand command = new SqlCommand(query, connection)) { connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { semesterCounts.Add(new SemesterStudentCount { Semester = reader.GetInt32(0), StudentCount = reader.GetInt32(1) }); } } } } // semesterCounts 就是统计结果列表
3. EF Core 实现映射
后续切换到EF Core时,同样可以使用这个DTO,有两种方式:
方式一:执行原生SQL并映射
var semesterCounts = context.Database .SqlQuery<SemesterStudentCount>(@"SELECT semester AS Semester, COUNT(*) AS StudentCount FROM Students GROUP BY semester;") .ToList();
方式二:使用LINQ查询
如果不想写原生SQL,可用EF Core的LINQ聚合查询直接生成统计结果:
var semesterCounts = context.Students .GroupBy(s => s.Semester) .Select(g => new SemesterStudentCount { Semester = g.Key, StudentCount = g.Count() }) .ToList();
内容的提问来源于stack exchange,提问作者user24437316
相关产品推荐
相关产品推荐

