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