2011-12-27 45 views
4

我有一个行动模型会议导航属性,为什么Linq GroupBy经过OrderBy驳回订单操作?

考虑以下代码:

var x=db.Actions.OrderBy(p => p.Session.Number).ThenBy(p => p.Date);//it's OK 

x是一个有序的动作,但是当X分组,组不上X迭代(基地上Action.Session)手动上有序枚举:

var y=x.GroupBy(p=>p.Session).ToArray() 

ÿHAV e一组(密钥,IGrouping)会话,但为什么group.Key 未订购基于Session.Number

如何通过数字和每个组按时间排序来达到一组会话顺序?

回答

3

因为它是Enumerable.GroupBy保留顺序。 Queryable.GroupBy没有这样的承诺。 从前者的文档:

的IGrouping(中TKEY的,TElement)对象产生的顺序基于 为了使所产生的每个 IGrouping的第一密钥在源中的元素(附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(); 
+0

谢谢,我编辑我的问题。 – 2011-12-27 12:15:42

+0

@RedHat我已经通过回答更新了,但不幸的是我现在无法检查供应商是否支持此功能。你可以尝试一下,或者我会尝试它,并在我有机会时适时更新答案。 – hvd 2011-12-27 12:30:16

+0

感谢@hvd为你的笔记,你的答案是好的,但我没有找到接受(会话,动作)=> ...的GroupBy方法的重载,我也回答下面的问题。 – 2011-12-27 12:45:46

2

因为没有定义GroupBy保留插入顺序或底层键顺序(与Dictionay<,>对本地内存中的工作没有这种保证的方式相同)。只是顺序分组之后,而不是:

var y = db.Actions.GroupBy(p=>p.Session).OrderBy(grp => grp.Key).ToArray(); 

在特别需要注意的顺序直接翻译就需要它来分析表达被发现与分组排序重叠的部分(和不),这是不平凡的。

+0

感谢您的提醒,我想排序组密钥基于Session.Number和每个组按Action.Date排序,如何做?我编辑我的问题。 – 2011-12-27 12:11:51

+0

@RedHat为此,您可以*尝试*将OrderBy(x => x.Date)放在第一行,其中Number是 – 2011-12-27 13:04:35

0

只是名称GroupBy表明在此刻查询的数据将根据提供的参数进行分组,聚合(根据您的需要调用)到另一个数据单元中。

一般来说,如果你想看到结果sorted函数调用应该是最后一个顺序。

+0

谢谢,我编辑我的问题。 – 2011-12-27 12:15:26

0

感谢@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();