C#父子ID的表数据转换成Tree型Json数据

C#父子ID的表数据转换成Tree型Json数据

在开发中有许多需要生成树型JSON数据的情况,比如侧边栏菜单、组织结构等,下面为两种JSON格式的数据生成方法。

1.现在有这样字段的父子结构的表

public class Node
{
    /// <summary>
    /// id
    /// </summary>
    public int id { get; set; }
    /// <summary>
    /// 上级id
    /// </summary>
    public int pid { get; set; }

    public string text { get; set; }
}

2.生成第一种格式的树型JSON字符串:

  • JSON数据
[
    {
        "id":1,
        "pid":0,
        "text":"节点1",
        "children":[
            {
                "id":2,
                "pid":1,
                "text":"节点1->2",
                "children":[
                    {
                        "id":4,
                        "pid":2,
                        "text":"节点1->2->4",
                        "children":[]
                    },
                    {
                        "id":5,
                        "pid":2,
                        "text":"节点1->2->5",
                        "children":[]
                    }
                ]
            },
            {
                "id":3,
                "pid":1,
                "text":"节点1->3",
                "children":[

                ]
            }
        ]
    },
    {
        "id":6,
        "pid":0,
        "text":"节点6",
        "children":[
            {
                "id":7,
                "pid":6,
                "text":"节点6->7",
                "children":[
                    {
                        "id":8,
                        "pid":7,
                        "text":"节点6->7->8",
                        "children":[]
                    }
                ]
            }
        ]
    }
]
  • 方案一:

    使用泛型,通过反射生成IEnumerable<object>对象,再进行序列化

(1). 实现

///泛型K为pid的数据类型
public static IEnumerable<object> GetChildrenTreeNode<T, K>(IEnumerable<T> notes,
                                                            Func<T, K> idSelector,
                                                            Func<T, K> parentIdSelector,
                                                            K rootId = default(K))
    where T : class
    {
        var dView = notes.Where(x =>
                               {
                                   K pid = parentIdSelector(x);
                                   return (rootId == null && pid == null) || (rootId != null && pid.Equals(rootId));
                               });
        // List<Object> objList = new List<object>();
        foreach (var dr in dView)
        {
            var testType = typeof(T);
            var propertyInfos = testType.GetProperties(BindingFlags.Instance
                                                       | BindingFlags.Public
                                                       | BindingFlags.NonPublic
                                                       | BindingFlags.Static);

            //******************获取源对象数据****************//
            Dictionary<string, object> dicObj = new Dictionary<string, object>();

            foreach (var property in propertyInfos)
            {
                var value = property?.GetValue(dr);
                if (value != null)
                {
                    dicObj.Add(property.Name, value);
                }
            }

            var children = GetChildrenTreeNode(notes, idSelector, parentIdSelector, idSelector(dr));
            dicObj.Add("children", children);
            //objList.Add(dicObj);
            yield return dicObj;
        }
        // return objList;
    }
  • 方案二

    先定义类NoteView,返回IEnumerable<NodeView>,再进行序列化

(1). 定义NoteView

public class NodeView
{
    public int id { get; set; }
    public int pid { get; set; }
    public string text { get; set; }
    public IEnumerable<NodeView> children { get; set; }
}

(2). 实现

///pid为最*note的id
private IEnumerable<NodeView> GetChildrenTreeNode(IEnumerable<Node> notes, int pid = 0)
{
    var noteList = notes.Where(x =>
                               {
                                   return pid.Equals(x.pid);
                               });

    //List<NodeView> noteViews = new List<NodeView>();
    foreach (var note in noteList)
    {
        var view = new NodeView();
        view.id = note.id;
        view.pid = note.pid;
        view.text = note.text;
        view.children = GetChildrenTreeNode(notes, note.id);
        //noteViews.Add(view);
        yield return view;
    }
    // return noteViews;
}
  • 调用

List<Node> notes = new List<Node>();
notes.Add(new Node { id = 1, pid = 0, text = "节点1" });
notes.Add(new Node { id = 2, pid = 1, text = "节点1->2" });
notes.Add(new Node { id = 3, pid = 1, text = "节点1->3" });
notes.Add(new Node { id = 4, pid = 2, text = "节点1->2->4" });
notes.Add(new Node { id = 5, pid = 2, text = "节点1->2->5" });
notes.Add(new Node { id = 6, pid = 0, text = "节点6" });
notes.Add(new Node { id = 7, pid = 6, text = "节点6->7" });
notes.Add(new Node { id = 8, pid = 7, text = "节点6->7->8" });
//dt.Add(new Node { id = 9, pid = 1, text = "节点1->9" });
//方案一
var treeNotes1 = GetChildrenTreeNode(notes, x => x.id, y => y.pid);
string jsonStr1 = Newtonsoft.Json.JsonConvert.SerializeObject(treeNotes1);
Console.WriteLine(jsonStr1);
//方案二
var treeNotes2 = GetChildrenTreeNode(notes);
string jsonStr2 = Newtonsoft.Json.JsonConvert.SerializeObject(treeNotes2);
Console.WriteLine(jsonStr2);

3.生成第二种格式的树型JSON字符串:

  • JSON数据

和前一种数据的格式不同

[
    {
        "Item": {
            "id": 1,
            "pid": 0,
            "text": "节点1"
        },
        "Children": [
            {
                "Item": {
                    "id": 2,
                    "pid": 1,
                    "text": "节点1->2"
                },
                "Children": [
                    {
                        "Item": {
                            "id": 4,
                            "pid": 2,
                            "text": "节点1->2->4"
                        },
                        "Children": []
                    },
                    {
                        "Item": {
                            "id": 5,
                            "pid": 2,
                            "text": "节点1->2->5"
                        },
                        "Children": []
                    }
                ]
            },
            {
                "Item": {
                    "id": 3,
                    "pid": 1,
                    "text": "节点1->3"
                },
                "Children": []
            }
        ]
    },
    {
        "Item": {
            "id": 6,
            "pid": 0,
            "text": "节点6"
        },
        "Children": [
            {
                "Item": {
                    "id": 7,
                    "pid": 6,
                    "text": "节点6->7"
                },
                "Children": [
                    {
                        "Item": {
                            "id": 8,
                            "pid": 7,
                            "text": "节点6->7->8"
                        },
                        "Children": []
                    }
                ]
            }
        ]
    }
]

(1). TreeItem定义

public class TreeItem<T>
{
    public T Item { get; set; }
    public IEnumerable<TreeItem<T>> Children { get; set; }
}

(2). 实现

public static IEnumerable<TreeItem<T>> GetChildrenTreeNode<T, K>(IEnumerable<T> notes,
                                                                  Func<T, K> idSelector,
                                                                  Func<T, K> parentIdSelector,
                                                                  K rootId = default(K))
{
    foreach (var c in notes.Where(u =>
                                  {
                                      var selector = parentIdSelector(u);
                                      return (rootId == null && selector == null)
                                          || (rootId != null && rootId.Equals(selector));
                                  }))
    {
        yield return new TreeItem<T>
        {
            Item = c,
            Children = GetChildrenTreeNode(notes, idSelector, parentIdSelector, idSelector(c))
        };
    }
}
  • 调用

示例中notes的数据初始化同上

//...
//`notes`的数据初始化同上
var treeNotes3 = GetChildrenTreeNode2(notes, x => x.id, y => y.pid);
string jsonStr3 = Newtonsoft.Json.JsonConvert.SerializeObject(treeNotes3);
Console.WriteLine(jsonStr3);
上一篇:【RStudio+R语言_NoteS】R语言课程练习_加深理解


下一篇:Winform 限制文本框输入整数为0-50