目录
一、需求:
给小明一家生成族谱树
二、实现代码
using Newtonsoft.Json;
using System.Collections.Generic;
using System;
using System.Linq;
class Person
{
public int Id { get; set; }
public int? ParentID { get; set; }
public string Name { get; set; }
}
class TreeDto : Person
{
[JsonProperty(Order = 99)]
public List<TreeDto> Children = new List<TreeDto>();
}
class Program
{
static void Main()
{
List<Person> PersonList = new List<Person>()
{
new Person(){ Id=1,ParentID=null,Name="小明曾祖父",},
new Person(){ Id=2,ParentID=1,Name="小明爷爷",},
new Person(){ Id=3,ParentID=1,Name="小明二爷爷",},
new Person(){ Id=4,ParentID=1,Name="小明三爷爷",},
new Person(){ Id=5,ParentID=2,Name="小明爸爸",},
new Person(){ Id=6,ParentID=2,Name="小明叔叔",},
new Person(){ Id=7,ParentID=5,Name="小明本人",},
new Person(){ Id=8,ParentID=5,Name="小明妹妹",},
new Person(){ Id=9,ParentID=7,Name="小明儿子",}
};
TreeDto tree = BuildTree(PersonList);//传入列表根节点【小明曾祖父】
var result = JsonConvert.SerializeObject(tree);//实体=>JSON打印
Console.WriteLine(result);
}
static TreeDto BuildTree(List<Person> PersonList,int? parentId=null) //入参:原始列表,父级ID 出参:满足父级ID的子级
{
var children = PersonList
.Where(p => p.ParentID == parentId)//寻找子级
.Select(p => new TreeDto
{
Id = p.Id,
ParentID = p.ParentID,
Name = p.Name,
Children = BuildTree(PersonList,p.Id).Children //递归:寻找子级的子级
})
.ToList();
return new TreeDto
{
Id = 0, //树根节点ID,可任意起名
ParentID = 0, //树根节点PID,可任意起名
Name = "族谱",
Children = children
};
}
}
【效果】
{
"Id": 0,
"ParentID": 0,
"Name": "族谱",
"Children": [
{
"Id": 1,
"ParentID": null,
"Name": "小明曾祖父",
"Children": [
{
"Id": 2,
"ParentID": 1,
"Name": "小明爷爷",
"Children": [
{
"Id": 5,
"ParentID": 2,
"Name": "小明爸爸",
"Children": [
{
"Id": 7,
"ParentID": 5,
"Name": "小明本人",
"Children": [
{
"Id": 9,
"ParentID": 7,
"Name": "小明儿子",
"Children": []
}
]
},
{
"Id": 8,
"ParentID": 5,
"Name": "小明妹妹",
"Children": []
}
]
},
{
"Id": 6,
"ParentID": 2,
"Name": "小明叔叔",
"Children": []
}
]
},
{
"Id": 3,
"ParentID": 1,
"Name": "小明二爷爷",
"Children": []
},
{
"Id": 4,
"ParentID": 1,
"Name": "小明三爷爷",
"Children": []
}
]
}
]
}
三、递归代码
static TreeDto BuildTree(List<Person> PersonList,int? parentId=null) //入参:原始列表,父级ID 出参:满足父级ID的子级
{
var children = PersonList
.Where(p => p.ParentID == parentId)//寻找子级
.Select(p => new TreeDto
{
Id = p.Id,
ParentID = p.ParentID,
Name = p.Name,
Children = BuildTree(PersonList,p.Id).Children //递归:寻找子级的子级
})
.ToList();
return new TreeDto
{
Id = 0, //树根节点ID,可任意起名
ParentID = 0, //树根节点PID,可任意起名
Name = "族谱",
Children = children
};
}
四、思考
1.设定序列化的字段顺序,例如将Children这个字段放最后面
2.如果根节点不想设为族谱,如何获取从曾祖父开始的递归树
将
var result = JsonConvert.SerializeObject(tree);//族谱开始
改为
var result = JsonConvert.SerializeObject(tree.Children.FirstOrDefault());//曾祖父开始
3.如果想在族谱上加一个根节点,如何操作
【代码】
TreeDto tree = BuildTree(PersonList);//传入列表根节点【小明曾祖父】
var newTree = new TreeDto
{
Id = 1000,
Name = "新增根节点",
Children = new List<TreeDto>() { tree }
};
var result = JsonConvert.SerializeObject(newTree);//实体=>JSON打印
【效果】