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

如何通过LINQ从SQL Server结果集中分组并构建嵌套JSON结构?

解决SQL Server结果集重复数据转嵌套JSON的LINQ实现方案

我之前处理过类似的报表场景,完全懂你遇到的痛点——存储过程返回的扁平化结果因为订单多商品导致重复,要转成CustomerReport -> SaleOrder -> SalesOrderItem的嵌套结构还得保留ReportSequence的显示顺序对吧?

先理清楚核心问题:原始结果集里,同一个订单的每一条数据对应一个商品,所以我们需要先按客户聚合,再在客户下按订单聚合商品,同时要确保整个层级的顺序和ReportSequence一致。

步骤1:定义扁平数据的临时实体

首先,假设从存储过程拿到的原始数据是一个IEnumerable<FlatReportRecord>集合,这个实体包含所有返回字段(包括客户、订单、商品的属性,以及ReportSequence):

public class FlatReportRecord
{
    // 客户字段
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
    // 订单字段
    public int SalesOrderId { get; set; }
    public DateTime OrderDate { get; set; }
    // 商品字段
    public int ItemId { get; set; }
    public string ItemName { get; set; }
    public decimal ItemPrice { get; set; }
    // 报表排序字段
    public int ReportSequence { get; set; }
}

步骤2:用LINQ实现嵌套转换

这里的关键是先按客户分组,再在每个客户组内按订单分组,同时利用ReportSequence保证排序(因为原始数据的顺序是报表要显示的顺序,所以分组前先排序更稳妥):

// 假设flatReportData是从存储过程获取的原始结果集
var nestedReport = flatReportData
    // 先按ReportSequence排序,确保后续分组不打乱报表显示顺序
    .OrderBy(r => r.ReportSequence)
    // 第一步:按客户维度分组(用CustomerId作为分组键,确保同一个客户的所有订单归在一起)
    .GroupBy(r => new { r.CustomerId, r.CustomerName })
    .Select(customerGroup => new CustomerReport
    {
        CustomerId = customerGroup.Key.CustomerId,
        CustomerName = customerGroup.Key.CustomerName,
        // 第二步:在客户组内,按订单维度分组
        SaleOrders = customerGroup
            .GroupBy(orderItem => new { orderItem.SalesOrderId, orderItem.OrderDate })
            .Select(orderGroup => new SaleOrder
            {
                SalesOrderId = orderGroup.Key.SalesOrderId,
                OrderDate = orderGroup.Key.OrderDate,
                // 收集当前订单下的所有商品
                SalesOrderItems = orderGroup
                    .Select(item => new SalesOrderItem
                    {
                        ItemId = item.ItemId,
                        ItemName = item.ItemName,
                        ItemPrice = item.ItemPrice
                    })
                    .ToList()
            })
            .ToList()
    })
    .ToList();

为什么之前按SalesOrderId分组会失败?

大概率是因为你跳过了客户层级的分组,直接按订单分组会导致不同客户的同ID订单(虽然实际业务中不太可能,但逻辑上会出问题)被合并,或者没有先按ReportSequence排序,导致最终嵌套结构的顺序不符合报表要求。

最后转成JSON

用Newtonsoft.Json或者System.Text.Json序列化即可:

// Newtonsoft.Json示例
string jsonResult = JsonConvert.SerializeObject(nestedReport, Formatting.Indented);

// System.Text.Json示例
string jsonResult = JsonSerializer.Serialize(nestedReport, new JsonSerializerOptions { WriteIndented = true });

这个方案既解决了重复数据的聚合问题,又严格保留了ReportSequence定义的报表显示顺序,完全适配你的嵌套实体结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:02:07