从结构化数据构建 JSON 层次结构

Build JSON Hierarchy from Structured Data(从结构化数据构建 JSON 层次结构)
本文介绍了从结构化数据构建 JSON 层次结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

C# |.NET 4.5 |实体框架 5

我有从 SQL 查询返回的 ID、ParentID、Name 形式的数据.我想获取该数据并将其解析为分层 JSON 字符串.到目前为止,这似乎是一项比应有的艰巨任务.由于我使用的是实体,因此数据作为 IEnumerable 很好地返回给我.现在我相信我只需要某种形式的递归,但我不太确定从哪里开始.任何帮助表示赞赏.

数据返回为

<上一页>id parentId 名称1 1 顶部位置2 1 位置 13 1 位置 24 2 位置1A

代码是

public static string GetJsonLocationHierarchy(long locationID){使用(实体设置上下文 = 新实体设置()){//ID,ParentID,Name 的 IEnumerablecontext.GetLocationHierarchy(locationID);}}

我希望的最终结果是这样的:

<代码>{id":1",父ID":1","名称": "TopLoc",孩子们": [{id":2",父ID":1",名称":Loc1",孩子们": [{id":4",parentId":2",名称":Loc1A",孩子们": [{}]}]},{id":3",父ID":1",名称":Loc2",孩子们": [{}]}]}

解决方案

将平面表转换为层次结构的一种方法是将所有节点放入字典中.然后遍历字典,并为每个节点查找其父节点并将其添加到父节点的子节点.从那里,您只需要找到根并对其进行序列化.

这是一个演示该方法的示例程序:

类程序{静态无效主要(字符串 [] 参数){IEnumerable<Location>位置=新列表<位置>{新位置 { Id = 1,ParentId = 1,名称 =TopLoc"},新位置 { Id = 2,ParentId = 1,名称 =Loc1"},新位置 { Id = 3, ParentId = 1, Name = "Loc2" },新位置 { Id = 4, ParentId = 2, Name = "Loc1A" },};字典<int,位置>dict = locations.ToDictionary(loc => loc.Id);foreach(dict.Values 中的位置 loc){if (loc.ParentId != loc.Id){位置父 = dict[loc.ParentId];父.子.Add(loc);}}位置根 = dict.Values.First(loc => loc.ParentId == loc.Id);JsonSerializerSettings 设置 = 新的 JsonSerializerSettings{ContractResolver = new CamelCasePropertyNamesContractResolver(),格式 = 格式.缩进};字符串 json = JsonConvert.SerializeObject(root, 设置);Console.WriteLine(json);}}上课地点{公共位置(){孩子 = 新列表<位置>();}公共 int ID { 获取;放;}公共 int ParentId { 获取;放;}公共字符串名称 { 获取;放;}公共列表<位置>孩子{得到;放;}}

这是输出:

<代码>{身份证":1,父ID":1,"名称": "TopLoc",孩子们": [{身份证":2,父ID":1,名称":Loc1",孩子们": [{身份证":4,父ID":2,名称":Loc1A",孩子们": []}]},{身份证":3,父ID":1,名称":Loc2",孩子们": []}]}

C# | .NET 4.5 | Entity Framework 5

I have data coming back from a SQL Query in the form of ID,ParentID,Name. I'd like to take that data and parse it into a Hierarchical JSON string. So far it seems to be much more of a daunting task than it should be. Since I'm using Entity the data comes back nicely to me as an IEnumerable. Now I believe I just need some form of recursion, but I'm not quite sure where to start. Any help is appreciated.

Data Returns as

id   parentId    name
1    1           TopLoc
2    1           Loc1
3    1           Loc2
4    2           Loc1A

Code is

public static string GetJsonLocationHierarchy(long locationID)
{
    using (EntitiesSettings context = new EntitiesSettings())
    {
        // IEnumerable of ID,ParentID,Name
        context.GetLocationHierarchy(locationID);
    }
}

The end result I'd hope would be something like this:

{
    "id": "1",
    "parentId": "1",
    "name": "TopLoc",
    "children": [
        {
            "id": "2",
            "parentId": "1",
            "name": "Loc1",
            "children": [
                {
                    "id": "4",
                    "parentId": "2",
                    "name": "Loc1A",
                    "children": [
                        {}
                    ]
                }
            ]
        },
        {
            "id": "3",
            "parentId": "1",
            "name": "Loc2",
            "children": [
                {}
            ]
        }
    ]
}

解决方案

One way to turn a flat table into a hierarchy is to put all your nodes into a dictionary. Then iterate over the dictionary, and for each node, look up its parent and add it to the parent's children. From there, you just need to find the root and serialize it.

Here is an example program to demonstrate the approach:

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<Location> locations = new List<Location>
        {
            new Location { Id = 1, ParentId = 1, Name = "TopLoc" },
            new Location { Id = 2, ParentId = 1, Name = "Loc1" },
            new Location { Id = 3, ParentId = 1, Name = "Loc2" },
            new Location { Id = 4, ParentId = 2, Name = "Loc1A" },
        };

        Dictionary<int, Location> dict = locations.ToDictionary(loc => loc.Id);

        foreach (Location loc in dict.Values)
        {
            if (loc.ParentId != loc.Id)
            {
                Location parent = dict[loc.ParentId];
                parent.Children.Add(loc);
            }
        }

        Location root = dict.Values.First(loc => loc.ParentId == loc.Id);

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Formatting = Formatting.Indented
        };
        string json = JsonConvert.SerializeObject(root, settings);

        Console.WriteLine(json);
    }
}

class Location
{
    public Location()
    {
        Children = new List<Location>();
    }

    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public List<Location> Children { get; set; }
}

Here is the output:

{
  "id": 1,
  "parentId": 1,
  "name": "TopLoc",
  "children": [
    {
      "id": 2,
      "parentId": 1,
      "name": "Loc1",
      "children": [
        {
          "id": 4,
          "parentId": 2,
          "name": "Loc1A",
          "children": []
        }
      ]
    },
    {
      "id": 3,
      "parentId": 1,
      "name": "Loc2",
      "children": []
    }
  ]
}

这篇关于从结构化数据构建 JSON 层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Force JsonConvert.SerializeXmlNode to serialize node value as an Integer or a Boolean(强制 JsonConvert.SerializeXmlNode 将节点值序列化为整数或布尔值)
Using JSON to Serialize/Deserialize TimeSpan(使用 JSON 序列化/反序列化 TimeSpan)
Could not determine JSON object type for type quot;Classquot;(无法确定类型“Class的 JSON 对象类型.)
How to deserialize a JSONP response (preferably with JsonTextReader and not a string)?(如何反序列化 JSONP 响应(最好使用 JsonTextReader 而不是字符串)?)
how to de-serialize JSON data in which Timestamp it-self contains fields?(如何反序列化时间戳本身包含字段的JSON数据?)
JSON.Net custom contract serialization and Collections(JSON.Net 自定义合约序列化和集合)