2011-12-27 20 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();