6

我有这两个实体:

public class Course
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public virtual ICollection<Class> Classes { get; set; }
}

public class Class
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; } ]
    public Course Course { get; set; }
}

现在我需要按课程列出每个班级分组并按(降序)Course.StartDate 然后按 Class.StartTime 排序。我可以按课程分组并按 Course.StartDate 排序:

var myList = context.Classes
    .GroupBy(c => c.Course)
    .OrderByDescending(g => g.Key.StartDate).ToList()

但是无法通过 StartTime 对每个类进行排序。我试过这个:

var myList = context.Classes
    .OrderBy(c => c.StartTime)
    .GroupBy(c => c.Course)
    .OrderByDescending(g => g.Key.StartDate).ToList()

甚至这样:

var myList = context.Classes
    .GroupBy(c => c.Course)
    .OrderByDescending(g => g.Key.StartDate)
    .ThenBy(g => g.Select(c => c.StartTime)).ToList()

但是这些类永远不会按它的 StartTime 排序。

*为更好地说明而编辑:这是针对 WebService 的,我必须返回 aList<IGrouping<Course, Class>>并且我真的想要一种优雅的方式来执行此操作(即仅使用 Linq),而无需手动创建列表。除非当然不可能。

任何帮助都将不胜感激(我使用的是 EF 代码优先 4.3 顺便说一句)。

4

3 回答 3

2

看起来您确实需要一个列表列表,其中每个嵌套列表都按照您提到的附加条件进行排序。由于您按 分组Course,因此您可以按开始日期对进行排序,因为组中的每个条目都具有相同的开始日期。然后您可以将分组的元素投影到按开始时间排序的列表中:

var myList = context.Classes
    .GroupBy(c => c.Course)
    .OrderByDescending(g => g.Key.StartDate)
    .Select(g => g.OrderBy(c => c.StartTime).ToList())
    .ToList();
于 2012-04-09T22:13:32.113 回答
2

如果您需要保留签名,我建议如下:

var myList = context.Classes
                    .GroupBy(cc => cc.Course)
                    .OrderByDescending(gg => gg.Key.StartDate)
                    .ToArray() // <- stops EF and starts L2O
                    .SelectMany(gg => gg.OrderBy(cc => cc.StartTime))
                    .ToLookup(cc => cc.Course, cc => cc)
                    .ToList();

这会产生一种类型的签名:List<IGrouping<Course, Class>>并让它们按 . 正确排序StartTime。这依赖于ToLookup维护找到的订单的行为,并且可能会发生变化。

于 2012-04-24T13:12:44.117 回答
1

由于 EF 创建直接 SQL,因此不可能在同一 SQL 中进行包含排序的分组。

我建议使用 EF 在一个 Linq 语句中进行分组,并以 ToList() 结尾。而不是使用 Linq To Objects(在内存中)作为第二个 Linq 语句进行排序。

这应该运行得很快,因为对象已经分组。

所以这样的事情应该有效:

var myList = context.Classes
    .GroupBy(c => c.Course).ToList()
    .OrderByDescending(g => g.Key.StartDate).ToList()
于 2012-04-24T12:50:52.883 回答