我正在编写一个简单的测试应用程序,以展示如何对从EF上下文中获取的列表进行排序。
“目标”是获取一个列表,按Student.Name排序,然后按Subject.Name
排序public class Student
{
public string Name {get;set;}
public List<ExamScore> ExamScores{get;set;}
}
public class Subject
{
public string Name{get;set;}
}
public class ExamScore
{
public Subject Subject{get;set;}
public int Score{get;set;}
}
第一级排序很简单:
var list = con.Students
.Include(e => e.ExamScores
.Select(s => s.Subjects))
.OrderBy(x => x.Name) //student.Name
.ToList();
但是添加下一个级别让我感到困惑。
var list = con.Students
.Include(e => e.ExamScores
.Select(s => s.Subjects))
.OrderBy(x => x.Name) //student.Name
.ThenBy(y => y.ExamScores.???) //subject name???
.ToList();
输入
Student{"Jannie", ExamScore{ Subject{"Math"}, 90}}
Student{"Jannie", ExamScore{ Subject{"History"}, 70}}
Student{"Jannie", ExamScore{ Subject{"Science"}, 90}}
Student{"Koos", ExamScore{ Subject{"Xhosa"}, 83}}
Student{"Koos", ExamScore{ Subject{"Afrikaans"}, 74}}
Student{"Koos", ExamScore{ Subject{"English"}, 78}}
Student{"Pieter", ExamScore{ Subject{"Afrikaans"}, 65}}
Student{"Pieter", ExamScore{ Subject{"History"}, 80}}
Student{"Pieter", ExamScore{ Subject{"Math"}, 70}}
Student{"Sannie", ExamScore{ Subject{"Science"}, 60}}
Student{"Sannie", ExamScore{ Subject{"Math"}, 55}}
Student{"Sannie", ExamScore{ Subject{"Biology"}, 75}}
Student{"Magriet", ExamScore{ Subject{"Biology"}, 75}}
Student{"Magriet", ExamScore{ Subject{"English"}, 80}}
Student{"Magriet", ExamScore{ Subject{"Science"}, 90}}
预期输出
Student{"Jannie", ExamScore{ Subject{"History"}, 70}}
Student{"Jannie", ExamScore{ Subject{"Math"}, 90}}
Student{"Jannie", ExamScore{ Subject{"Science"}, 90}}
Student{"Koos", ExamScore{ Subject{"Afrikaans"}, 74}}
Student{"Koos", ExamScore{ Subject{"English"}, 78}}
Student{"Koos", ExamScore{ Subject{"Xhosa"}, 83}}
Student{"Magriet", ExamScore{ Subject{"Biology"}, 75}}
Student{"Magriet", ExamScore{ Subject{"English"}, 80}}
Student{"Magriet", ExamScore{ Subject{"Science"}, 90}}
Student{"Pieter", ExamScore{ Subject{"Afrikaans"}, 65}}
Student{"Pieter", ExamScore{ Subject{"History"}, 80}}
Student{"Pieter", ExamScore{ Subject{"Math"}, 70}}
Student{"Sannie", ExamScore{ Subject{"Biology"}, 75}}
Student{"Sannie", ExamScore{ Subject{"Math"}, 55}}
Student{"Sannie", ExamScore{ Subject{"Science"}, 60}}
答案 0 :(得分:7)
您需要做的是首先展开Student-&gt;主题关系然后您将能够对两者进行排序:
var list = con.Students.Include(e => e.ExamScores.Select(s => s.Subjects))
.SelectMany(student => student.ExamScores.Select(score => new { Student = student, Score = score }))
.OrderBy(x => x.Student.Name)
.ThenBy(x => x.Score.Subject.Name);
这将产生一个可枚举的匿名对象,其中包含按学生姓名和科目名称排序的学生和分数。
答案 1 :(得分:1)
您可以使用.SelectMany()
作为Dmitri建议。这里有一个可编辑的工作实例来说明他的答案(我回答的时候正在研究这个问题,所以我不想浪费它,但他的答案是正确的,我当然也赞成了):< / p>
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public class Student
{
public string Name { get; set; }
public List<ExamScore> ExamScores { get; set; }
}
public class Subject
{
public string Name { get; set; }
}
public class ExamScore
{
public Subject Subject
{
get;
set;
}
public int Score { get; set; }
}
static class Program
{
static void Main()
{
var students = new List<Student>
{
new Student
{
Name = "C",
ExamScores = new List<ExamScore>
{
new ExamScore {Subject = new Subject {Name = "Z"}, Score = 1},
new ExamScore {Subject = new Subject {Name = "Y"}, Score = 2},
new ExamScore {Subject = new Subject {Name = "X"}, Score = 3},
}
},
new Student
{
Name = "B",
ExamScores = new List<ExamScore>
{
new ExamScore {Subject = new Subject {Name = "Z"}, Score = 4},
new ExamScore {Subject = new Subject {Name = "Y"}, Score = 5},
new ExamScore {Subject = new Subject {Name = "X"}, Score = 6},
}
},
new Student
{
Name = "A",
ExamScores = new List<ExamScore>
{
new ExamScore {Subject = new Subject {Name = "Z"}, Score = 7},
new ExamScore {Subject = new Subject {Name = "Y"}, Score = 8},
new ExamScore {Subject = new Subject {Name = "X"}, Score = 9},
}
}
};
var orderedStudents =
students.SelectMany(s => s.ExamScores.Select(e => new {Student = s, ExamScore = e}))
.OrderBy(x => x.Student.Name)
.ThenBy(x => x.ExamScore.Subject.Name);
foreach (var item in orderedStudents)
{
Console.WriteLine($"{item.Student.Name} {item.ExamScore.Subject.Name} {item.ExamScore.Score}");
}
}
}
}