为什么Linq GroupBy在OrderBy之后解雇订单操作?
我有一个带有会话导航属性的Action模型,
考虑以下代码:
var x=db.Actions.OrderBy(p => p.Session.Number).ThenBy(p => p.Date);//it's OK
x是一个有序的Action,但是当在x上分组时,group不会在有序的enumerable上手动迭代x(基于Action.Session ):
var y=x.GroupBy(p=>p.Session).ToArray()
你有一个组(密钥,组合)的会话,但为什么group.Key 没有基于Session.Number 排序 ?
如何按编号和按日期排序的每个组达到一组会话顺序?
因为它是保存顺序的Enumerable.GroupBy
。 对Queryable.GroupBy
没有这样的承诺。 从前者的文件:
IGrouping(Of TKey,TElement)对象是根据源中元素的顺序产生的,这些元素产生每个IGrouping的第一个键(Of TKey,TElement)。 分组中的元素按它们在源中出现的顺序生成。
你打电话给后者,上面没有提到。 在GroupBy
之后调用OrderBy
使其工作。
更新 :因为您显然希望排序的不仅仅是GroupBy键,您应该能够使用另一个GroupBy重载来指定每个会话的操作列表是否要排序:
db.Actions.GroupBy( p => p.Session, (session, actions) => new { Session = session, Actions = actions.OrderBy(p => p.Date) }).OrderBy(p => p.Session.Number).ToArray();
因为没有定义GroupBy保留插入顺序或底层键顺序(就像Dictionay<,>
没有这样的保证,对于本地内存工作)。 只需在分组后订购,而不是:
var y = db.Actions.GroupBy(p=>p.Session).OrderBy(grp => grp.Key).ToArray();
特别要注意的是,要直接翻译顺序,需要它分析表达式以找出排序的哪些部分与分组重叠(哪些不重要),这是非平凡的。
感谢@Marc Gravell和@hvd关于groupby IGrouping(Of TKey,TElement)的注释不保留TKey的顺序但保留了TElement的顺序。
所以我对最后一个问题的答案(如何按编号和按日期排序的每个组达到一组会话顺序?)是:
var x= db.Actions .OrderBy(p => p.ActionDateTime) .GroupBy(p => p.Session) .OrderBy(q => q.Key.Number) .ToArray();
只有名称GroupBy
建议在那一刻查询的数据将根据提供的参数进行分组,聚合(根据需要调用)到另一个数据单元。
通常,如果要查看结果sorted
则Sort()
函数调用应该是序列中的最后一个。