【问题标题】:How to Serialize Tree Structure Data From Database to JSON如何将树结构数据从数据库序列化为 JSON
【发布时间】:2017-03-30 09:55:32
【问题描述】:

我的数据存储中有一个表示树结构的数据。以下代码表示如何在 C# 中的简单 DataTable 中对其进行描述。

using System.Data;

namespace DemoConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable treeData = new DataTable();
            treeData.Clear();
            treeData.Columns.Add("NodeId", typeof(int));
            treeData.Columns.Add("ParentNodeId", typeof(int));
            treeData.Columns.Add("Data", typeof(string));
            treeData.Columns.Add("AbsolutePath", typeof(string));

            DataRow record1 = treeData.NewRow();
            record1["NodeId"] = 1;
            record1["ParentNodeId"] = 0;
            record1["Data"] = "Dairy";
            record1["AbsolutePath"] = "/Dairy/";
            treeData.Rows.Add(record1);

            DataRow record2 = treeData.NewRow();
            record2["NodeId"] = 2;
            record2["ParentNodeId"] = 1;
            record2["Data"] = "Yoghurt";
            record2["AbsolutePath"] = "/Dairy/Yoghurt";
            treeData.Rows.Add(record2);

            DataRow record3 = treeData.NewRow();
            record3["NodeId"] = 3;
            record3["ParentNodeId"] = 1;
            record3["Data"] = "Cheese";
            record3["AbsolutePath"] = "/Dairy/Cheese";
            treeData.Rows.Add(record3);

            DataRow record4 = treeData.NewRow();
            record4["NodeId"] = 4;
            record4["ParentNodeId"] = 2;
            record4["Data"] = "Flavored";
            record4["AbsolutePath"] = "/Dairy/Yoghurt/Flavored";
            treeData.Rows.Add(record4);
        }
    }
}

我需要将数据序列化成如下结构。

{
  "TreeData": {
    "NodeId" : "1",
    "Data" : "Dairy",
    "Children": [
      {
        "NodeId": "2",
        "Data": "Yohurt",
        "Children": [
          {
              "NodeId": "4",
              "Data": "Flavored",
              "Children": []
          }
        ]
      },
      {
        "NodeId": "3",
        "Data": "Cheese",
        "Children": []
      }
    ]
  }
}

我该如何实现这一目标?

【问题讨论】:

  • 您是如何尝试实现转换的?你试过JSON.net吗?
  • 感谢评论,我用过JSON.net,我的问题是,如何遍历数据并用JSON表示。

标签: c# json tree


【解决方案1】:

创建一个新类:

class Node
{
    public int NodeId;
    public int ParentNodeId;
    public string Data;
    public string AbsolutePath;
    public List<Node> Children = new List<Node>();
}

然后遍历 DataTable 的行,创建适当的树结构并简单地调用 JsonConvert.SerializeObject()

var nodes = new Dictionary<int, Node>();
foreach(DataRow record in treeData.Rows)
{
    var node = new Node { NodeId = (int)record["NodeId"], ParentNodeId = (int)record["ParentNodeId"], Data = (string)record["Data"], AbsolutePath = (string)record["AbsolutePath"] };
    nodes.Add(node.NodeId, node);
}

var rootNodeId = 1;
var rootNode = nodes[rootNodeId];
foreach(var keyValuePair in nodes)
{
    var node = keyValuePair.Value;
    if(node.NodeId != rootNodeId)
    {
        nodes[node.ParentNodeId].Children.Add(node);
    }
}

string json = JsonConvert.SerializeObject(rootNode, Formatting.Indented);
Debug.WriteLine(json);

输出:

{
  "NodeId": 1,
  "ParentNodeId": 1,
  "Data": "Dairy",
  "AbsolutePath": "/Dairy/",
  "Children": [
    {
      "NodeId": 2,
      "ParentNodeId": 1,
      "Data": "Yoghurt",
      "AbsolutePath": "/Dairy/Yoghurt",
      "Children": [
        {
          "NodeId": 4,
          "ParentNodeId": 1,
          "Data": "Flavored",
          "AbsolutePath": "/Dairy/Flavored",
          "Children": []
        }
      ]
    },
    {
      "NodeId": 3,
      "ParentNodeId": 1,
      "Data": "Cheese",
      "AbsolutePath": "/Dairy/Cheese",
      "Children": []
    }
  ]
}

【讨论】:

  • 感谢您的回答。但是我不能手动编码数据存储中的每一行! (我给出的是一个例子)我正在寻找的是迭代逻辑。确实是这个问题。
  • 我已经根据迭代逻辑更新了答案。
【解决方案2】:
you need to make custom recursive function with Serialization Class
which will append Children till you get leaf node.
Below is example for that. please use your logic to append JsonString
var appendJsonString;

Private string PassParentId(int Id)
{
      var childnodecount=0;
      childnodecount=getchildnode(Id);   
     while(childnodecount>0)
     {
       getchilddata=getchildnode(Id);
       childnodecount=getchilddata.count();
       appendJsonString = getchilddata();
    }
    return appendJsonString;
}

【讨论】:

    【解决方案3】:

    我的方法是创建一个对象(例如 TreeDataNode)并为该对象提供以下变量

    public class TreeDataNode{
        int nodeId;
        string data;
        List<TreeDataNode> children;
    
        public void AddChildren(string relativePath, TreeDataNode node)
        {
            string[] path = relativePath.Split('/');
            if(path.Count<2)
            {
                children.Add(node);
            }else
            {
                string newPath = String.Join(@"/", relativePath.Split('\\').Skip(1));
                children.First(n=> n.data==path[0]).AddChildren(newPath,node);
            }
        }
    }
    

    一旦您填充了这个对象,拥有一个父 TreeDataNode 和后续的子节点,您只需使用任何标准 JSON 序列化程序对其进行序列化,您将拥有一个与您尝试实现的结构一样的结构。

    现在,您只需要确保按顺序添加对象,不要在孩子之后添加父母,就可以了。使用根对象创建您的父 TreeDataNode,然后为该父对象上的每个对象调用 AddChildren。

    【讨论】:

    • 感谢您的回答,但它只是在 C# 中表示 JSON,我需要知道的是一种遍历数据并填充您建议的类的对象的方法。
    • 一旦你有了这个对象,你只需要迭代你的DataTable(或者你有原始数据的地方)并使用像“AddChildren(string AbsolutePath)”这样的对象来填充它,你可以在其中选择正确的父级使用绝对路径并添加一个新的子节点
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2010-10-30
    • 2020-10-03
    相关资源
    最近更新 更多