C#与ASP.NET MVC实现数据库多行学生成绩合并为单行展示的方法
问题原因
你当前直接返回数据库原始的Student实体列表,数据库中每个学生的每个科目对应一条独立记录,所以视图渲染时会按数据库行数输出,自然出现学生姓名重复的问题,需要同时调整控制器查询逻辑和视图绑定逻辑,核心是完成数据的行转列聚合。
调整步骤
第一步:新增视图模型
首先定义专门用来给视图传输聚合后学生成绩的视图模型,放到项目的Models目录下即可:
public class StudentScoreViewModel { // 学生姓名 public string StudentName { get; set; } // 存储所有科目的成绩,key是科目名,value是分数 public Dictionary<string, int?> SubjectScores { get; set; } = new(); // 若科目固定,也可以单独定义属性,比如public int? M1 {get;set;},使用更简单 }
第二步:修改控制器Index查询逻辑
在控制器中对原始数据按学生分组,聚合每个学生的所有科目成绩:
public ActionResult Index() { using (studentdbentities dbmodel = new studentdbentities()) { // 按学生ID+姓名分组,聚合各科成绩 var studentScores = dbmodel.Students .ToList() .GroupBy(s => new { s.FStudentID, s.FStudentName }) .Select(g => new StudentScoreViewModel { StudentName = g.Key.FStudentName, SubjectScores = g.ToDictionary(s => s.FSubject, s => s.FMarks) }) .ToList(); // 提取所有去重的科目名,传递给视图生成表头 ViewBag.AllSubjects = dbmodel.Students.Select(s => s.FSubject).Distinct().OrderBy(s => s).ToList(); return View(studentScores); } }
第三步:修改视图渲染逻辑
视图顶部先绑定新的视图模型类型,然后动态生成表头和每行的成绩:
@model List<StudentScoreViewModel> <table border="1" cellpadding="5" cellspacing="0"> <thead> <tr> <th>姓名</th> @foreach (var subject in ViewBag.AllSubjects as List<string>) { <th>@subject</th> } </tr> </thead> <tbody> @foreach (var student in Model) { <tr> <td>@student.StudentName</td> @foreach (var subject in ViewBag.AllSubjects as List<string>) { <td>@(student.SubjectScores.TryGetValue(subject, out var score) ? score : "-")</td> } </tr> } </tbody> </table>
内容的提问来源于stack exchange,提问作者Nithya Muru
相关产品推荐
相关产品推荐

