在一些涉及到组织架构的场景, 比如ERP, OA系统中我们经常会需要用到树的结构。自己开发的时候也遇到了此使用场景,总结一下以后就可以直接拿来用了。

表设计如下:

代码如下:
public class Node
{
public int NodeId { get; set; } //节点Id
public int ParentId { get; set; } //节点父级Id 如果为0则为根节点
public string NodeName { get; set; } //节点名
public DateTime WriteTime { get; set; } // 备注
}
public class TreeNode
{
public int NodeId { get; set; } //节点Id
public int ParentId { get; set; } //节点父级Id 如果为0则为根节点
public string NodeName { get; set; } //节点名
public DateTime WriteTime { get; set; } //写入时间
public List<TreeNode> Children { get; set; }//子节点树
}
/// <summary>
/// 获取当前系统的结构树,可能多个树
/// </summary>
/// <returns></returns>
public List<TreeNode> GetSysNodeTree()
{
using (MySqlHelper mySqlHelper = new MySqlHelper("MySqlTestDB"))
{
List<TreeNode> treeNodeList = new List<TreeNode>();
//这一步数据库查询所有的记录 (避免递归中多次查询数据库)
List<Node> allNode = mySqlHelper.GetList_ExecuteSql<Node>("select * from tb_node");
//遍历所有的根节点
var rootList = allNode.Where(s => s.ParentId == 0).ToList();
foreach (var ent in rootList)
{
TreeNode treeNode = new TreeNode();
treeNode.NodeId = ent.NodeId;
treeNode.NodeName = ent.NodeName;
treeNode.ParentId = ent.ParentId;
treeNode.Children = GetChildrenTree(ent.NodeId, allNode);
treeNodeList.Add(treeNode);
}
return treeNodeList;
}
}
/// <summary>
/// 获取当前节点的节点树
/// </summary>
/// <param name="curNodeId"></param>
/// <param name="allNode"></param>
/// <returns></returns>
public List<TreeNode> GetChildrenTree(int curNodeId, List<Node> allNode)
{
if (allNode == null || allNode.Count <= 0)
return new List<TreeNode>();
List<TreeNode> TreeList = new List<TreeNode>();
List<Node> children = allNode.Where(s => s.ParentId == curNodeId).ToList();
foreach (var ent in children)
{
TreeNode treeNode = new TreeNode();
treeNode.NodeId = ent.NodeId;
treeNode.NodeName = ent.NodeName;
treeNode.ParentId = ent.ParentId;
treeNode.Children = GetChildrenTree(ent.NodeId, allNode);
TreeList.Add(treeNode);
}
return TreeList;
}
/// <summary>
/// 通过curNodeId 获取自己以及递归下的所有子Node (用于删除功能等)
/// </summary>
/// <param name="curNodeId"></param>
/// <param name="allNode"></param>
/// <returns></returns>
public List<Node> GetRecurNodes(int curNodeId, List<Node> allNode)
{
if (curNodeId <= 0 || allNode==null)
{
return null;
}
List<Node> list = new List<Node>();
if (allNode.FirstOrDefault((m=>m.NodeId==curNodeId))!=null)
list.Add(allNode.FirstOrDefault((m => m.NodeId == curNodeId)));
List<Node> firstLevelNodes = allNode.Where(m => m.ParentId == curNodeId).ToList();
foreach (var node in firstLevelNodes)
{
list.AddRange(GetRecurNodes(node.NodeId, allNode));
}
return list;
}
然后前端拿到数据,同样递归展示就OK了。
转载注明出处-祥子