我有一个具有一对多关系的实体。但是我需要按照一定的顺序收集子集。这是一个例子:
public class Course
{
public int ID{get;set;}
public string Name{get;set;}
public virtual ICollection<Student> Students{get;set;}
}
public class Student
{
public int ID{get;set;}
public string FirstName{get;set;}
public string LastName{get;set;}
public decimal Grade{get;set;}
}
使用关键字virtual
导致Students
集合的延迟加载,因此当我将其序列化为JSON并通过Web API发送时,它基本上会自动填充学生列表。但是,我总是要求那些学生按照一定的顺序,例如从最高到最低等级。这就是我想出的:
var course=db.Courses.Find(id);
course.Students=course.Students.OrderByDescending(s=>s.Grade).ToArray();
这似乎有效,但我担心这不是最有效的方法。
所以我的问题是:是否有更好的方法来确保子集合具有指定的顺序?假设我总是希望子集合按此顺序排列,我是否应该指定virtual
并避免延迟加载?如果排序顺序比OrderBy
条款中包含的顺序更复杂(例如,按年度顺序排列学生,然后按年级按年级排序),答案是否会改变?
答案 0 :(得分:1)
好的,我做了一些测试,根据Derck的回答,这就是我最终做的事情:
var course=db.Courses.Include(x=>x.Students).SingleOrDefault(x=>x.ID==id);
course.Students=course.Students.OrderByDescending(s=>s.Grade).ToList();
对于一些解释:似乎没有任何方法可以编写一个对子集合进行排序的linq whery(CarbineCoder的答案仍然不起作用),这必须单独完成。为了防止多个数据库调用,我使用了Include
子句,该子句急切加载了Students
集合,以便可以在内存中进行排序。 Include
无法与Find
一起使用,这就是我使用SingleOrDefault
的原因。但是,OrderBy
不是一个改变方法,这就是为什么Seabizkit的答案不能正常工作 - 你必须将集合设置为等于OrderBy
返回的结果。
答案 1 :(得分:0)
您可以通过向查询中添加Include语句来使用Eager-Loading来获取数据。如果您使用延迟加载,它将始终加载数据,无论您是否需要它。
db.Courses.Include(x=>x.Students)
.SingleOrDefault(x => x== id)
.OrderByDescending(s=>s.Students.Grade).ToArray();
答案 2 :(得分:0)
试试这个,应该有用......
var data = db.Courses.Include(x=>x.Students)
.SingleOrDefault(x=>x.ID == id);
data.Students.OrderByDescending(x => x.Grade);
如果您在许多课程中这样做,您可以执行类似
的操作var data = db.Courses.Include(x=>x.Students)
.Where(x=>x.Name.Contains("high"))
.ToList();
List<Courses> res = data.ForEach(x => x.Students = x.Students
.OrderByDescending(x => x.Grade)
.ToList())
.ToList();
结果将是所有学生的课程。