如何将树结构数据从数据库序列化为JSON

时间:2017-03-30 09:55:32

标签: c# json tree

我在数据存储中有数据表示树结构。下面的代码表示如何在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": []
      }
    ]
  }
}

我如何实现这一目标?

3 个答案:

答案 0 :(得分: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": []
    }
  ]
}

答案 1 :(得分:0)

我的方法是创建一个对象(例如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。

答案 2 :(得分:0)

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;
}