原文:https://www.cnblogs.com/fzz2727551894/p/5501223.html
简单测试:
代码:
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { public class Class6 { //https://www.cnblogs.com/fzz2727551894/p/5501223.html public void test1() { var dt = ExecuteDataTable($"select * from Table_1 ", null); List<TreeNode> tree = TreeServices.ToTree(dt); Console.WriteLine(tree.Count); } // 返回DataTable public static DataTable ExecuteDataTable(string sql, params SqlParameter[] param) { string conStr = "data source=.\\sqlexpress;initial catalog=TEST1;user id=sa;password=sa;"; //string conStr = "data source=192.168.2.51; initial catalog=BIMManagerDb;user id=sa;password=Sql123456; "; DataTable dt = new DataTable(); using (SqlConnection con = new SqlConnection(conStr)) { using (SqlDataAdapter adapter = new SqlDataAdapter(sql, con)) { //添加参数 if (param != null) { adapter.SelectCommand.Parameters.AddRange(param); } //1.打开链接,如果连接没有打开,则它给你打开;如果打开,就算了 //2.去执行sql语句,读取数据库 //3.sqlDataReader,把读取到的数据填充到内存表中 adapter.Fill(dt); } } return dt; } } public static class k1 { public static bool IsEmpty(this string str) { return false; } public static bool IsEmpty(this DataTable dt) { if (dt == null) { return true; } if (dt.Rows.Count <= 0) { return true; } return false; } public static int ToInt32(this object obj) { return int.Parse(obj.ToString()); } public static bool IsEmpty<T>(this List<T> list) where T : class, new() { return false; } } public class TreeServices { /// <summary> /// 以非递归的方式生成树 /// </summary> /// <param name="table"></param> /// <returns></returns> public static List<TreeNode> ToTree(DataTable table) { var list = new List<TreeNode>(); if (table.IsEmpty()) return list; var dic = TreeNode.FillModel(table); foreach (var pair in dic) { var pid = pair.Value.ParentId; if (pid == 0) { list.Add(pair.Value); continue; } if (dic.ContainsKey(pid)) { dic[pid].Children.Add(pair.Value); } } return list; } } public class TreeNode { public TreeNode() { Children = new List<TreeNode>(); } /// <summary> /// 自增Id /// </summary> public int NodeId { get; set; } /// <summary> /// 关联Id,形式1-2-3-4(该节点上一节点为4,再上一级为3,...) /// </summary> public string RelationId { get; set; } /// <summary> /// 上一个节点的Id /// </summary> public int ParentId { get { if (RelationId.IsEmpty()) return 0; var s = RelationId.Split('-'); return s[s.Length - 1].ToInt32(); } } /// <summary> /// 是否有下一节点 /// </summary> public bool HasChild { get { return Children.IsEmpty(); } } /// <summary> /// 子节点集合 /// </summary> public List<TreeNode> Children { get; set; } /// <summary> /// DataTable To Dictionary /// </summary> /// <param name="table"></param> /// <returns></returns> public static Dictionary<int, TreeNode> FillModel(DataTable table) { var list = new Dictionary<int, TreeNode>(); if (table == null || table.Rows.Count == 0) return list; foreach (DataRow row in table.Rows) { var model = new TreeNode { NodeId = row["Id"].ToInt32(), RelationId = row["RelationId"].ToString() }; list.Add(model.NodeId, model); } return list; } } }
SQL:
USE [TEST1] GO /****** Object: Table [dbo].[Table_1] Script Date: 03/11/2020 11:36:54 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Table_1]( [Id] [int] NOT NULL, [RelationId] [nvarchar](max) NULL, [ParentId] [int] NULL, CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (1, N'0', 0) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (2, N'1', 1) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (3, N'1', 1) INSERT [dbo].[Table_1] ([Id], [RelationId], [ParentId]) VALUES (4, N'1-3', 3)