LINQ查询以获得每门课程中的优秀学生(最高分)

时间:2016-01-21 22:23:08

标签: c# linq

我试图获得一个在课程中得分最高的学生名单。 我有一个学生班和一门课程如下:

public class Student
{
    public string First { get; set; }
    public string Last { get; set; }
    public int ID { get; set; }
    public Level Year { get; set; }
    public List<Course> Courses;
}

public class Course
{
    public string Name { get; set; }
    public int Score { get; set; }
}

学生班有课程列表。每个课程都有姓名和分数。

这是数据源

public List<Student> students = new List<Student>
    {
        new Student {First="Svetlana", Last="Omelchenko", ID=111, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 97 }, 
                new Course { Name = "Science", Score = 92}, 
                new Course { Name = "English", Score = 81}, 
                new Course { Name = "Arts", Score = 60}}},
        new Student {First="Claire", Last="O'Donnell", ID=112, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 75 }, 
                new Course { Name = "Science", Score = 84}, 
                new Course { Name = "English", Score = 91}, 
                new Course { Name = "Arts", Score = 39}}},
        new Student {First="Sven", Last="Mortensen", ID=113, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 88 }, 
                new Course { Name = "Science", Score = 94}, 
                new Course { Name = "English", Score = 65}, 
                new Course { Name = "Arts", Score = 91}}}, 
        new Student {First="Cesar", Last="Garcia", ID=114, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 97 }, 
                new Course { Name = "Science", Score = 89}, 
                new Course { Name = "English", Score = 85}, 
                new Course { Name = "Arts", Score = 82}}},
        new Student {First="Debra", Last="Garcia", ID=115, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 35 }, 
                new Course { Name = "Science", Score = 72}, 
                new Course { Name = "English", Score = 92}, 
                new Course { Name = "Arts", Score = 70}}},
        new Student {First="Fadi", Last="Fakhouri", ID=116, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 99 }, 
                new Course { Name = "Science", Score = 86}, 
                new Course { Name = "English", Score = 90}, 
                new Course { Name = "Arts", Score = 94}}},
        new Student {First="Hanying", Last="Feng", ID=117, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 93 }, 
                new Course { Name = "Science", Score = 92}, 
                new Course { Name = "English", Score = 80}, 
                new Course { Name = "Arts", Score = 87}}},
        new Student {First="Hugo", Last="Garcia", ID=118, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 92 }, 
                new Course { Name = "Science", Score = 90}, 
                new Course { Name = "English", Score = 83}, 
                new Course { Name = "Arts", Score = 78}}},
        new Student {First="Lance", Last="Tucker", ID=119, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 68 }, 
                new Course { Name = "Science", Score = 79}, 
                new Course { Name = "English", Score = 88}, 
                new Course { Name = "Arts", Score = 92}}},
        new Student {First="Terry", Last="Adams", ID=120, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 99 }, 
                new Course { Name = "Science", Score = 82}, 
                new Course { Name = "English", Score = 81}, 
                new Course { Name = "Arts", Score = 79}}},
        new Student {First="Eugene", Last="Zabokritski", ID=121, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 96 }, 
                new Course { Name = "Science", Score = 85}, 
                new Course { Name = "English", Score = 91}, 
                new Course { Name = "Arts", Score = 60}}},
        new Student {First="Michael", Last="Tucker", ID=122, Year = Level.First,
            Courses = new List<Course> {
                new Course { Name = "Maths", Score = 94 }, 
                new Course { Name = "Science", Score = 92}, 
                new Course { Name = "English", Score = 91}, 
                new Course { Name = "Arts", Score = 91}}}
    };

我试图获得如下输出:

Math:
    Fadi Fakhouri- 99
Science:
    Svetlana Omelchenko - 92
    Michael Tucker - 92
English:
    Debra Garcia - 92
Arts:
    Fadi Fakhouri - 94

我的LINQ查询应该是什么样的?

2 个答案:

答案 0 :(得分:0)

以下是许多方法之一

var allCourses = students.SelectMany(s => s.Courses);
var groupedByCourse = allCourses.GroupBy(c => c.Name);  
foreach (var courseGroup in groupedByCourse)
{
    Console.WriteLine(courseGroup.Key + ":");
    int maxMark = courseGroup.Max(g => g.Score);
    var studentsWithMaxMark = students.Where(s => s.Courses.Any(c => c.Name == courseGroup.Key && c.Score == maxMark));
    foreach (var student in studentsWithMaxMark)
    {
        Console.WriteLine("\t" + student.First + " " + student.Last + " - " + maxMark);
    }
}

输出以下内容:

Maths:
  Fadi Fakhouri - 99
  Terry Adams - 99
Science:
  Sven Mortensen - 94
English:
  Debra Garcia - 92
Arts:
  Fadi Fakhouri - 94

以上IMO是明确且可读的。您可以在一个LINQ查询中完成所有操作。

答案 1 :(得分:0)

这是我使用Linq的另一种方式。

var query = from student in db.students
                    from course in student.Courses
                    group course by course.Name into g
                    select new
                    {
                        CourseName = g.Key,
                        Marks = g.Max(c => c.Score),
                        studentGroup = (
                            from student in db.students
                            let maxMark = g.Max(c => c.Score)
                            where student.Courses.Any(c => c.Name == g.Key && c.Score == maxMark)
                            select student
                        )
                    };

        foreach(var group in query)
        {
            Console.WriteLine("Course: {0}", group.CourseName);
            foreach (var student in group.studentGroup)
            {
                Console.WriteLine("\t{0} {1} : {2}", student.First, student.Last, group.Marks);
            }
        }