why Linq GroupBy After OrderBy dismissed order operation?

霸气de小男生 提交于 2020-01-03 17:25:38

问题


I have a Action model with Session Navigation Property,

Consider this code:

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

x is a ordered Action, but when grouped on x, group not iterate on x(base on Action.Session) manually on ordered enumerable:

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

y have a group(Key,IGrouping) of sessions but why group.Key not ordered base on Session.Number?

How to i reached a group of Session order by number and each group ordered by date?


回答1:


Because it's Enumerable.GroupBy that preserves order. No such promise is made for Queryable.GroupBy. From the documentation of the former:

The IGrouping(Of TKey, TElement) objects are yielded in an order based on order of the elements in source that produced the first key of each IGrouping(Of TKey, TElement). Elements in a grouping are yielded in the order they appear in source.

You're calling the latter, and the above is not mentioned. Call OrderBy after GroupBy to make it work.

Update: since you apparently want to sort on more than just the GroupBy key, you should be able to use another GroupBy overload to specify that each session's list of actions is to be sorted:

db.Actions.GroupBy(
    p => p.Session,
    (session, actions) => new {
        Session = session,
        Actions = actions.OrderBy(p => p.Date)
    }).OrderBy(p => p.Session.Number).ToArray();



回答2:


Because it is not defined that GroupBy preserves either insertion order or the underlying key order (in the same way that Dictionay<,> makes no such guarantee, for local in-memory work). Just order after grouping, instead:

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

In particular, note that to translate the order directly would require it to analyse the expression to spot which parts of the ordering overlap with the grouping (and which don't), which is non-trivial.




回答3:


Thanks to @Marc Gravell & @hvd for note about groupby IGrouping(Of TKey, TElement) not preserves order of TKey but preserves order of TElement.

So my answer for my final question (How to i reached a group of Session order by number and each group ordered by date?) is:

var x= db.Actions
.OrderBy(p => p.ActionDateTime)
.GroupBy(p => p.Session)
.OrderBy(q => q.Key.Number)
.ToArray();



回答4:


Just the name GroupBy suggests that the data queried at that moment will be grouped, aggregated (call how you want) into another data unit based on parameter provided.

In general if you want to see result sorted the Sort() function call should be the last one in sequence.



来源:https://stackoverflow.com/questions/8644384/why-linq-groupby-after-orderby-dismissed-order-operation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!