C#多层嵌套JSON处理及分层ID查询效率问题咨询
Hey there! 首先得纠正一个小问题——你给出的示例JSON其实不符合标准JSON语法哦,JSON里的对象必须有明确的字符串键,不能直接嵌套无键的对象。不过你的分层ID思路非常合理,当JSON数据量较大时,这种结构能让查询操作直接定位到目标数据,避免遍历整个数据集,效率提升很明显。
第一步:定义符合标准的目标JSON结构
先给你调整成合法且满足需求的JSON格式,这样后续C#序列化/反序列化才能正常工作:
{ "001": { "01": { "01": { "string": "this is some information.", "int": 9371 } }, "02": { "01": { "string": "blah blah blah.", "int": 2241 } } } }
这里的层级关系很清晰:
- 顶层键是Primary ID(比如"001")
- 第二层键是Secondary ID(比如"01"、"02")
- 第三层键是Tertiary ID(比如"01")
- 最终对应包含
string和int字段的数据对象
第二步:C#中对应的类/结构定义
你可以用嵌套的Dictionary来实现这个分层结构,既灵活又符合JSON的键值对特性。当然也可以定义显式的类,可读性会更好,这里两种方式都给你参考:
方式1:显式嵌套类(可读性优先)
// 最底层的数据实体类 public class DataItem { public string String { get; set; } public int Int { get; set; } } // 第三层:Tertiary ID -> 数据实体 public class TertiaryLayer : Dictionary<string, DataItem> { } // 第二层:Secondary ID -> 第三层结构 public class SecondaryLayer : Dictionary<string, TertiaryLayer> { } // 顶层:Primary ID -> 第二层结构 public class PrimaryLayer : Dictionary<string, SecondaryLayer> { }
方式2:直接用嵌套字典(简洁优先)
如果不想定义太多类,也可以直接用Dictionary<string, Dictionary<string, Dictionary<string, DataItem>>>,效果是一样的,只是代码里的层级嵌套看起来会深一些。
第三步:序列化(将数据保存为JSON文件)
C#里常用的JSON序列化库有System.Text.Json(.NET Core 3.0+内置)和Newtonsoft.Json(Json.NET),这里用内置的System.Text.Json举例子:
using System.Text.Json; using System.IO; // 构建你的测试数据 var dataStore = new PrimaryLayer { ["001"] = new SecondaryLayer { ["01"] = new TertiaryLayer { ["01"] = new DataItem { String = "this is some information.", Int = 9371 } }, ["02"] = new TertiaryLayer { ["01"] = new DataItem { String = "blah blah blah.", Int = 2241 } } } }; // 配置序列化选项(开启格式化,让JSON更易读) var serializeOptions = new JsonSerializerOptions { WriteIndented = true }; // 序列化并写入文件 string jsonContent = JsonSerializer.Serialize(dataStore, serializeOptions); File.WriteAllText("data.json", jsonContent);
第四步:反序列化(读取JSON文件并还原数据)
要读取保存的JSON文件,只需要反向操作即可:
// 读取文件内容 string jsonFromFile = File.ReadAllText("data.json"); // 反序列化为我们定义的结构 var loadedDataStore = JsonSerializer.Deserialize<PrimaryLayer>(jsonFromFile);
第五步:通过三级ID组合查询数据
有了分层字典结构,查询操作就非常高效了(时间复杂度O(1)),直接通过键值定位即可:
// 拆分三级ID组合 string targetId = "001-02-01"; string[] idParts = targetId.Split('-'); string primaryId = idParts[0]; string secondaryId = idParts[1]; string tertiaryId = idParts[2]; // 逐层查询,避免空引用异常 if (loadedDataStore.TryGetValue(primaryId, out var secondaryLayer) && secondaryLayer.TryGetValue(secondaryId, out var tertiaryLayer) && tertiaryLayer.TryGetValue(tertiaryId, out var targetData)) { Console.WriteLine($"查询结果:String = {targetData.String}, Int = {targetData.Int}"); } else { Console.WriteLine("指定的三级ID组合不存在"); }
额外小提示
如果你的.NET版本支持(.NET 5+),可以用record类型简化DataItem的定义,代码会更简洁:
public record DataItem(string String, int Int);
内容的提问来源于stack exchange,提问作者Kabir
相关产品推荐
相关产品推荐

