递归生成部门树

SQL Server 递归查询部门参考脚本:

USE [TestDb]
GO
/****** Object:  Table [dbo].[Department]    Script Date: 2019/8/7 10:47:00 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [DepartmentName] [nvarchar](200) NULL,
    [ParentId] [int] NULL,
    [Version] [timestamp] NULL,
 CONSTRAINT [PK_Department] 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]

GO
SET IDENTITY_INSERT [dbo].[Department] ON 

INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (1, N'营销部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (2, N'研发部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (3, N'行政部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (4, N'财务部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (5, N'品质部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (6, N'生产部', 0)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (7, N'系统集成部', 1)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (8, N'销售部', 1)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (9, N'市场商务部', 1)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (10, N'采购部', 2)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (11, N'硬件部', 2)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (12, N'人力资源部', 3)
INSERT [dbo].[Department] ([Id], [DepartmentName], [ParentId]) VALUES (13, N'集成软件组', 7)
SET IDENTITY_INSERT [dbo].[Department] OFF
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Description: 根据一级部门的Id,递归查询其下的所有部门
-- =============================================
CREATE FUNCTION GetDepartmentByParentId
(    
    @parentId int
)
RETURNS TABLE 
AS
RETURN 
(
    -- Add the SELECT statement with parameter references here
    WITH CTE1
    AS
    (
        SELECT ParentId AS pId, Id, DepartmentName FROM TESTDB.DBO.Department WHERE ParentId = @parentId
                
        UNION ALL
        
        SELECT CTE.Id AS pId, C.Id, C.DepartmentName FROM TESTDB.DBO.Department C JOIN CTE1 CTE ON C.ParentId = CTE.Id
    )
    SELECT pId, Id, DepartmentName FROM CTE1
    --UNION ALL --合并一级部门本身
    --SELECT ParentId AS pId, Id, DepartmentName FROM TESTDB.DBO.Department WHERE Id = @parentId
)
GO
DECLARE @TAB TABLE 
(
    TOPID INT,
    PID INT,
    ID INT,
    Department NVARCHAR(100)
)
    
DECLARE @ID INT;
    
DECLARE CUR CURSOR FOR
SELECT ID FROM Department WHERE PARENTID = 0

OPEN CUR
FETCH NEXT FROM CUR INTO @ID 
WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO @TAB 
    SELECT @ID, PID, ID, DepartmentName FROM TestDb.DBO.GetDepartmentByParentId(@ID)
    FETCH NEXT FROM CUR INTO @ID
END     

CLOSE CUR
DEALLOCATE CUR
     
SELECT * FROM @TAB

利用 ADO.NET 从数据库获取部门数据,然后按深度优先依次生成部门树结构:

//窗体加载事件
private void Form_Load(object sender, EventArgs e)
{
    TreeNode root;

    //先设置根节点为起始位置
    root = treeView1.Nodes[0];
//然后获取所有的节点数据,并缓存,方便后面筛选子节点 DataSet ds = SQLHelper.Query(SQLHelper._connstr, "SELECT deptId,parentId,deptCode,deptName,level FROM Department"); List<DeptDto> all = ExtensionMethod.ConvertToModel<DeptDto>(ds.Tables[0]);
//递归生成树 LoadTreeRecursive(all, root, "0"); treeView1.ExpandAll(); } //递归生成树结构 private void LoadTreeRecursive(List<TypeDetail> dataList, TreeNode curNode, string curId) { List<DeptDto> children = dataList.Where(d => d.fore_id.Trim() == curId).ToList(); foreach (TypeDetail type in children) //当children为空时会自动停止执行 { TreeNode node; node = new TreeNode(type.type_name); node.ImageIndex = 1; node.SelectedImageIndex = 1; node.Tag = type;
//按深度优先,逐层添加子节点 curNode.Nodes.Add(node); //搜索下一层 LoadTreeRecursive(dataList, node, ((TypeDetail)node.Tag).type_id); } } //DataTable 转 List<T> 的扩展方法 public static List<T> ConvertToModel<T>(this DataTable table) where T : new() { var list = new List<T>(); PropertyInfo[] propertys = typeof(T).GetProperties(); foreach (DataRow row in table.Rows) { T model = Activator.CreateInstance<T>(); foreach (PropertyInfo pi in propertys) { var tempName = pi.Name; if (!table.Columns.Contains(tempName)) continue; if (!pi.CanWrite) continue; object value = Convert.ToString(row[tempName]); if (value != DBNull.Value) { pi.SetValue(model, value, null); } } list.Add(model); } return list; } //表结构对应的实体类 public class DeptDto { public string deptId { get; set; } public string parentId { get; set; } public string deptCode { get; set; } public string deptName { get; set; } public string level { get; set; } }
原文地址:https://www.cnblogs.com/hellowzl/p/10273694.html