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

如何用C#扁平化拆分包含多订单项的订单列表?

解决方案

核心思路

通过DTO类适配原始JSON字段,结合LINQ的SelectMany方法实现订单的扁平化拆分,同时处理JSON中字段名不一致的情况,代码简洁且逻辑清晰。

步骤实现

1. 定义适配JSON的DTO类

由于原始JSON的字段名与目标Order/OrderItem类不匹配,先定义中间DTO类来接收反序列化的数据:

using System.Text.Json.Serialization;

public class RawOrderDto
{
    [JsonPropertyName("order_id")]
    public int OrderID { get; set; }

    [JsonPropertyName("total_price")]
    public int TotalPrice { get; set; }

    [JsonPropertyName("items")]
    public List<RawOrderItemDto>? Items { get; set; }

    [JsonPropertyName("products_info")]
    public List<RawOrderItemDto>? ProductsInfo { get; set; }
}

public class RawOrderItemDto
{
    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("product_name")]
    public string? ProductName { get; set; }

    [JsonPropertyName("price")]
    public int Price { get; set; }

    [JsonPropertyName("product_price")]
    public int ProductPrice { get; set; }

    [JsonPropertyName("sku")]
    public string? SKU { get; set; }
}

2. 反序列化+拆分订单的核心逻辑

利用LINQ的SelectMany将每个原始订单拆分为多个单个订单项的订单,同时完成字段映射:

using System.Text.Json;
using System.Linq;

// 原始JSON字符串
var rawJson = @"[
    {
        ""order_id"": 1,
        ""total_price"": 700,
        ""items"": [
            {
                ""name"": ""cellphone"",
                ""price"": 500,
                ""sku"": ""1s4f""
            },
            {
                ""product_name"": ""airphones"",
                ""product_price"": 200,
                ""sku"": ""1ar4""
            }
        ]
    },
    {
        ""order_id"": 2,
        ""total_price"": 5000,
        ""products_info"": [
            {
                ""name"": ""car"",
                ""price"": 2500,
                ""sku"": ""8y5t""
            },
            {
                ""name"": ""battery"",
                ""price"": 1500,
                ""sku"": ""5g3g""
            },
            {
                ""name"": ""insurance"",
                ""price"": 1000,
                ""sku"": ""5r8f""
            }
        ]
    }
]";

// 反序列化到DTO列表
var rawOrders = JsonSerializer.Deserialize<List<RawOrderDto>>(rawJson) ?? [];

// 拆分并转换为目标Order类型
var splitOrders = rawOrders
    .SelectMany(rawOrder => 
    {
        // 兼容两种订单项字段名
        var items = rawOrder.Items ?? rawOrder.ProductsInfo ?? [];
        
        return items.Select((item, index) => new Order
        {
            // 用原ID+序号生成新订单ID,保持关联
            OrderID = int.Parse($"{rawOrder.OrderID}-{index + 1}"),
            // 单个订单项价格作为新订单总价
            TotalPrice = item.Price != 0 ? item.Price : item.ProductPrice,
            Items = new List<OrderItem>
            {
                new OrderItem
                {
                    Name = item.Name ?? item.ProductName,
                    Price = item.Price != 0 ? item.Price : item.ProductPrice,
                    SKU = item.SKU
                }
            }
        });
    })
    .ToList();

// 验证输出
foreach (var order in splitOrders)
{
    Console.WriteLine($"订单ID: {order.OrderID}, 总价: {order.TotalPrice}");
    Console.WriteLine($"商品: {order.Items[0].Name}, 价格: {order.Items[0].Price}, SKU: {order.Items[0].SKU}");
    Console.WriteLine("---");
}

方案优势

  • 可读性高:LINQ链式调用清晰表达"拆分每个订单为单个订单项订单"的逻辑。
  • 兼容性强:处理了JSON中字段名不一致的情况(如items/products_info、name/product_name)。
  • 低侵入性:无需修改原有Order/OrderItem类,通过DTO做中间适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 12:18:27