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

如何在C#中高效反序列化含子属性的JSON为单个对象

高效处理3000万条JSON记录的Newtonsoft.Json反序列化方案

针对你要处理3000万条带嵌套parameters的JSON记录、还要把嵌套属性扁平化到顶层Event类的需求,我给你几个比当前嵌套类+LINQ映射更高效的方案,能大幅降低内存占用、提升处理速度:

1. 自定义JsonConverter直接完成反序列化+扁平化

最推荐的方式是写一个自定义转换器,在反序列化过程中直接把parameters里的属性映射到顶层Event对象,省去先转嵌套类再二次映射的中间步骤——这对3000万条数据来说,能减少大量临时对象的创建,内存和性能都会好很多。

转换器代码示例:

public class EventConverter : JsonConverter<Event>
{
    public override Event ReadJson(JsonReader reader, Type objectType, Event existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 加载单个JSON对象
        JObject jsonObj = JObject.Load(reader);
        Event evt = new Event();

        // 读取顶层固定属性
        evt.udid = jsonObj["udid"]?.ToString();
        evt.date = jsonObj["date"]?.ToObject<DateTime>() ?? DateTime.MinValue;
        evt.event_id = jsonObj["event_id"]?.ToObject<int>() ?? 0;

        // 读取并扁平化parameters里的可变属性
        JObject parameters = jsonObj["parameters"] as JObject;
        if (parameters != null)
        {
            evt.gender = parameters["gender"]?.ToString();
            evt.age = parameters["age"]?.ToObject<int>() ?? 0;
            evt.country = parameters["country"]?.ToString();
            evt.stage = parameters["stage"]?.ToObject<int>() ?? 0;
            evt.win = parameters["win"]?.ToObject<bool>() ?? false;
            evt.time = parameters["time"]?.ToObject<int>() ?? 0;
            evt.income = parameters["income"]?.ToObject<int>() ?? 0;
            evt.name = parameters["name"]?.ToString();
            evt.price = parameters["price"]?.ToObject<double>() ?? 0.0;
            evt.item = parameters["item"]?.ToString();
        }

        return evt;
    }

    // 如果不需要序列化Event对象到JSON,这个方法可以留空或者抛出异常
    public override void WriteJson(JsonWriter writer, Event value, JsonSerializer serializer)
    {
        throw new NotImplementedException("序列化暂未实现");
    }
}

使用方式:

var serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new EventConverter());

// 直接反序列化为扁平化的Event列表
List<Event> events = JsonConvert.DeserializeObject<List<Event>>(jsonContent, serializerSettings);

2. 流式分批处理(应对超大规模数据)

如果你的JSON文件大到一次性加载到内存会溢出(3000万条数据很可能会这样),可以结合流式读取+自定义转换器,逐对象处理,避免一次性加载所有数据:

using (StreamReader streamReader = new StreamReader("your-large-data.json"))
using (JsonTextReader jsonReader = new JsonTextReader(streamReader))
{
    // 允许读取多个JSON对象
    jsonReader.SupportMultipleContent = true;
    var serializer = JsonSerializer.Create(new JsonSerializerSettings { Converters = { new EventConverter() } });

    while (jsonReader.Read())
    {
        // 只处理单个JSON对象的起始标记
        if (jsonReader.TokenType == JsonToken.StartObject)
        {
            Event evt = serializer.Deserialize<Event>(jsonReader);
            // 这里可以把evt加入批量处理队列,比如每1000条写入数据库,避免内存堆积
        }
    }
}

这种方式的内存占用几乎是恒定的,完全不用担心大文件导致的内存溢出问题。

3. 优化现有LINQ映射方案(如果坚持用嵌套类)

如果你还是想保留嵌套类的方式,可以对现有代码做两个关键优化:

  • 避免一次性创建两个超大List,改用遍历处理,减少内存占用
  • 去掉不必要的中间对象,直接在遍历过程中生成Event并处理

优化后的代码示例:

using (StreamReader sr = new StreamReader("data.json"))
using (JsonTextReader reader = new JsonTextReader(sr))
{
    var serializer = new JsonSerializer();
    // 直接遍历反序列化后的嵌套对象,不转成List
    foreach (EventNested nested in serializer.Deserialize<IEnumerable<EventNested>>(reader))
    {
        Event evt = new Event
        {
            date = nested.date,
            udid = nested.udid,
            event_id = nested.event_id,
            gender = nested.Parameters?.gender,
            age = nested.Parameters?.age ?? 0,
            country = nested.Parameters?.country,
            stage = nested.Parameters?.stage ?? 0,
            win = nested.Parameters?.win ?? false,
            time = nested.Parameters?.time ?? 0,
            income = nested.Parameters?.income ?? 0,
            name = nested.Parameters?.name,
            price = nested.Parameters?.price ?? 0.0,
            item = nested.Parameters?.item
        };
        // 直接处理evt,比如加入批量插入集合
    }
}

总结

最适合你的场景是方案1+方案2结合:用自定义转换器直接完成扁平化反序列化,同时用流式读取分批处理,既能保证速度,又能控制内存占用,完美应对3000万条数据的处理需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:46:44