You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Linq高效按hubId分组无重复键值输出指定格式结果

问题背景

现有如下订单数据:

orders: 
[
    {id: 1, hubId: 1, number:1, IsTrue: true},
    {id: 2, hubId: 1, number:2, IsTrue: true},
    {id: 3, hubId: 1, number:3, IsTrue: false},
    {id: 4, hubId: 2, number:4, IsTrue: true},
    {id: 5, hubId: 2, number:5, IsTrue: true},
    {id: 6, hubId: 2, number:6, IsTrue: false}
]

需求为编写LINQ查询,按hubId对订单分组,输出如下指定格式的结果:

result: 
[
    {
        hubId: 1, 
        orders: 
            [
                {id: 1, number: 1},
                {id: 2, number: 2},
            ]
    },
    {
        hubId: 2, 
        orders: 
            [
                {id: 4, number: 4},
                {id: 5, number: 5},
            ]
    }
]

当前编写的初始查询无法输出符合格式要求的结果,初始代码如下:

var orders = _ordersRepo.GetQueryable<Order>().AsNoTracking()
    .Where(o => o.IsTrue)
    .Select(o => new  
    {
        hubId = o.hubId,
        number = o.number,
        id = o.id
    }).ToList()
    .GroupBy(o => o.hubId)

return orders;
问题原因

初始代码仅完成了分组操作,未对分组结果做结构投影。GroupBy方法默认返回IGrouping<TKey, TElement>类型的集合,和目标结构要求的包含hubId、orders两个属性的对象格式不匹配;同时初始写法在分组前调用ToList(),会将符合条件的数据全量加载到内存后再做分组,性能较差。

正确实现代码
var result = _ordersRepo.GetQueryable<Order>().AsNoTracking()
    .Where(o => o.IsTrue)
    .Select(o => new  
    {
        o.hubId,
        o.number,
        o.id
    })
    .GroupBy(o => o.hubId)
    .Select(g => new 
    {
        hubId = g.Key,
        orders = g.Select(o => new { o.id, o.number }).ToList()
    })
    .ToList();

return result;
实现说明
  • 过滤条件Where(o => o.IsTrue)前置,提前筛除无效数据,减少后续计算的数据量
  • 移除分组前的ToList()调用,让分组、投影操作可以被ORM翻译成SQL在数据库端执行,相比内存分组性能更高
  • 分组后通过分组键g.Key获取当前分组对应的hubId值
  • 对组内元素再次做投影,仅保留需要的id、number字段,输出结构完全匹配需求

内容的提问来源于stack exchange,提问作者Nour Mawla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 01:45:52