按数据库中的原始数据分组

Group By Raw Data from DB

这是我来自数据库的原始数据:

PrimaryColumn   StudentId  StudentName  CourseName  CourseId  CourseDuration
     1               1           X         Cse1       C1          2
     2               1           X         Cse2       C2          1 
     3               1           X         Cse3       C3          3
     4               2           Y         Cse1       C1          2
     5               2           Y         Cse4       C4          5

Classes 从 C# 结束:

public class Student 
{
  public int StudentId {get; set;}
  public string StudentName {get; set}
  public List<Course> Courses {get; set;}
}    

public class Course 
{
  public int CourseId {get; set;}
  public string CourseName {get; set;}
  public int CourseDuration {get; set; }
}

我的目标是获取按学生分组的数据以及他们将要参加的课程,这是使用 List<Course> 作为学生 Class 的 属性 完成的。

所以,我认为这个目标非常有前途。因此,我继续对从 DB 到 C# 的原始数据使用 GroupBy,希望得到结果但无济于事。

这是迄今为止我得到的最好的。

  masterData.GroupBy(x => new { x.StudentId, x.StudentName }, (key, group) => new { StudentId = key.StudentId, StudentName = key.StudentName, Courses=group.ToList() }).ToList();

虽然这并没有让我得到我希望得到的东西。通过一些小的代码解决方法 post 这个调用,我能够实现我需要的。但是,每次我无法正确分组原始数据都让我很恼火。

如果有人能告诉我进一步优化上述代码的正确方法或完全不同的方法,那将非常有帮助。

这就是我需要结果在 List<Student>:

中的方式
Student:
     StudentId: 1
     StudentName: X
     List<Course> Courses: [0] - { CourseId: C1, CourseName = Cse1, CourseDuration = 2}
                           [1] - { CourseId: C2, CourseName = Cse2, CourseDuration = 1}
                           [2] - { CourseId: C3, CourseName = Cse3, CourseDuration = 3} 
Student:
     StudentId: 2
     StudentName: Y
     List<Course> Courses: [0] - { CourseId: C1, CourseName = Cse1, CourseDuration = 2}
                           [1] - { CourseId: C4, CourseName = Cse4, CourseDuration = 5}

干杯

你可以这样做:

这里是完整的例子:dotNetFiddle

List<Student> result = data.GroupBy(x => new { x.StudentID, x.StrudentName }, 
            (key, group) => new Student{ 
                                          StudentId = key.StudentID, 
                                          StudentName = key.StrudentName,                
                                          Courses = GetCourses(group)}).ToList();

    //You can do this operation with Reflection if you want. If you don't want to write manually the property names.
    public static List<Course> GetCourses(IEnumerable<RawData> data)
    {
        List<Course> course = new List<Course>();

        foreach(var item in data)
        {
            Course c = new Course();

            c.CourseDuration = item.CourseDuration;
            c.CourseId = item.CourseID;
            c.CourseName = item.CourseName;

            course.Add(c);
        }

        return course;
    }

在你的情况下我会做什么(但我不确定你会认为它是 'properly grouping')是按照

var groupedStudents = masterData.GroupBy(x => x.StudentId);
foreach (var studentGroup in groupedStudents)
{
    // new studentclass
    var student = new Student(studentGroup.First().StudentId, studentGroup.First().StudentName);
    foreach (var studentRecord in studentGroup)
    {
        student.Courses.Add(new course(studentRecord.CourseId, studentRecord.CourseName, studentRecord.CourseDuration);
    }

    // add the student-object to where you want to save them i.e.
    this.MyStudentList.Add(student);
}

这里的问题是数据库组织不善并且远离规范化状态。但是您可以像将其正确分离到不同的表一样进行处理。通过这种方式,您提取了课程、学生,然后将它们聚合在一起——下面的代码应该提供线索

// get all courses
var courses = masterData.GroupBy(x => x.CourseId).Select(group => group.First())
.Select(x => new Course {CourseId = x.CourseId, CourseName = x.CourseName, ...})
.ToDictionary(x => x.CourseId);

// get all students (with empty courses for now)
var students = masterData.GroupBy(x => x.StudentId).Select(group => group.First())
.Select(x => new Student {StudentId = x.StudentId, ...})
.ToDictionary(x => x.StudentId);

// fill students with courses
foreach(var data in masterData)
{
    student[data.StudentId].Courses.Add(courses[data.CourseId]) 
}

我想这是一种清晰的方法,可以在表规范化后重复使用。或者,您可以尝试编写一个复杂的 LINQ,通过单个查询来处理所有这些工作人员