在实体框架6中对ICollections进行排序

时间:2016-03-18 12:19:32

标签: c# entity-framework

我有一个具有一对多关系的实体。但是我需要按照一定的顺序收集子集。这是一个例子:

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条款中包含的顺序更复杂(例如,按年度顺序排列学生,然后按年级按年级排序),答案是否会改变?

3 个答案:

答案 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();

结果将是所有学生的课程。