为什么Linq GroupBy在OrderBy之后驳回了订单操作?

发布于 2024-12-23 01:18:42 字数 518 浏览 5 评论 0原文

我有一个带有 Session 导航属性的 Action 模型,

请考虑以下代码:

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

x 是一个有序的 Action,但是当在 x 上分组时,组不会在 x 上迭代(基于 >Action.Session)手动处理有序枚举:

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

y有一组(Key,IGrouping)会话,但为什么group.Key未排序基于Session.Number >?

如何按编号到达一组会话并按日期排序每个组?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

写给空气的情书 2024-12-30 01:18:42

因为它是 Enumerable.GroupBy 保持秩序。对于 Queryable.GroupBy 没有做出此类承诺
从前者的文档来看:

IGrouping(Of 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();

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();
我的奇迹 2024-12-30 01:18:42

因为未定义 GroupBy 保留插入顺序或底层键顺序(与 Dictionay<,> 对于本地内存工作不提供此类保证的方式相同)。相反,只需在分组后进行排序:

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

特别要注意的是,要直接翻译顺序将要求它分析表达式,以发现排序的哪些部分与分组重叠(以及哪些部分不重叠),这是非常重要的。

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.

陌路黄昏 2024-12-30 01:18:42

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

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();
新雨望断虹 2024-12-30 01:18:42

仅名称 GroupBy 就表明此时查询的数据将根据提供的参数进行分组、聚合(按照您想要的方式调用)到另一个数据单元中。

一般来说,如果您想查看排序后的结果,则 Sort() 函数调用应该是按顺序的最后一个。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文