我们再数据库中存储的是列表结构,但是我们送给前端时候,需要转为树形结构,用一种最简单的方法进行转换,不破坏原有顺序
结构定义
首先我们定义一下结构,有父id孩子节点,和自身id:
public interface ITree<T>
{
/// <summary>
/// id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 父id
/// </summary>
public int ParentId { get; set; }
/// <summary>
/// 孩子节点
/// </summary>
public List<T> Children { get; set; }
}
列表转树
public static List<T> ListToTree<T>(this List<T> data) where T: class,ITree<T>
{
List<T> Tree = new List<T>();
foreach (var item in data)
{
if (item.ParentId == 0)
{
Tree.Add(item);
}
else
{
//查找源数据父节点
var ParentNode = data.SingleOrDefault(u => u.Id == item.ParentId);
if(ParentNode == null)
{
Tree.Add(item);//没有找到父节点,所以直接加入最上层节点
}
else
{
ParentNode.Children.Add(item);//加入父节点
}
}
}
return Tree;
}
先看代码,这里限制了T必须为class,很巧妙用了引用类型的特性,因为引用类型传递的是地址,所以先进行父id的判断,如果没有父节点,那么就是顶层节点,如果找到父节点,在原有列表中寻找父节点,如果有就加入,因为引用的特性,加入的是引用地址,所以不管父节点在不在树中,当父节点加入时候,孩子都可以加入。
树转列表
public static void TreeToList<T>(this List<T> data,List<T> list) where T : class, ITree<T>
{
foreach (var item in data)
{
list.Add(item);
if (item.Children!=null && item.Children.Count > 0)
{
TreeToList(item.Children,list);
}
}
}
这个就相对容易了,直接递归即可,递归也用到了引用类型的特性,终止条件就是没有孩子节点