使用C#从数据库表复制文件夹树并粘贴到同表目标文件夹
目录树形结构复制实现方案
需求背景
现有单个数据库及一张WorkingDirectory表,需用C#将源文件夹(RootFolder1,ID=1)的树形结构复制到同表的目标文件夹(RootFolder2,ID=5)下。
传入参数(UI/Swagger)
[ { "copySourceFolderId": 1, "pasteDestinationFolderId": 5 } ]
初始表结构
| Id | ParentId | Name |
|---|---|---|
| 1 | null | RootFolder1 |
| 2 | 1 | SubFolder1 |
| 3 | 1 | SubFolder2 |
| 4 | 2 | SubSubFolder1 |
| 5 | null | RootFolder2 |
实现步骤
步骤1:递归查询获取源目录树形结构
通过递归SQL查询获取源文件夹的N级树形结构,存入workingDirectoryList对象:
递归SQL
with recursive subordinate as ( select "Id" ,"Name" ,"ParentId" from ol."WorkingDirectory" w where "Id" = 1 union select wd2."Id" ,wd2."Name" ,wd2."ParentId" from ol."WorkingDirectory" wd2 inner join subordinate s on s."Id"= wd2."ParentId" ) select s."Id",s."Name",s."ParentId" from subordinate s group by s."Id",s."Name",s."ParentId" order by s."Id" asc
C#模型及集合定义
public class WorkingDirectoryModel { public int Id { get; set; } public int? ParentId { get; set; } public string Name { get; set; } } List<WorkingDirectoryModel> workingDirectoryList = new List<WorkingDirectoryModel>();
步骤2:循环插入逻辑实现
核心是维护原目录与新目录的ID映射,确保复制后的树形结构父子关系正确。完整实现代码如下:
// 存储原目录ID到新插入目录ID的映射,保证子目录能找到正确的父节点 Dictionary<int, int> oldToNewIdMap = new Dictionary<int, int>(); // 从传入参数中获取目标文件夹ID int pasteDestinationFolderId = 5; foreach (var item in workingDirectoryList) { // 创建新的目录实体 var newDirectory = new WorkingDirectoryModel { Name = item.Name, // 确定新的父节点ID: // 源根目录的父节点设为目标文件夹ID;子目录用映射表中的新ID替代原父ID ParentId = item.ParentId == null ? pasteDestinationFolderId : oldToNewIdMap[item.ParentId.Value] }; // 插入数据库(这里以EF Core为例,实际可替换为ADO.NET等数据库操作) _context.WorkingDirectory.Add(newDirectory); _context.SaveChanges(); // 记录原ID与新ID的映射,供后续子目录使用 oldToNewIdMap.Add(item.Id, newDirectory.Id); }
逻辑说明
- ID映射表:因为新插入的目录会生成自增ID,必须用映射表跟踪原ID和新ID的对应关系,才能保证子目录的父节点指向正确的新目录。
- 根目录处理:源文件夹的根节点(原ParentId为null),新父节点直接设为目标文件夹ID。
- 子目录处理:非根目录的新父节点从映射表中获取原父ID对应的新ID,维持原树形层级。
步骤3:预期结果
复制完成后WorkingDirectory表结构如下:
| Id | ParentId | Name |
|---|---|---|
| 1 | null | RootFolder1 |
| 2 | 1 | SubFolder1 |
| 3 | 1 | SubFolder2 |
| 4 | 2 | SubSubFolder1 |
| 5 | null | RootFolder2 |
| 6 | 5 | RootFolder1 |
| 7 | 6 | SubFolder1 |
| 8 | 6 | SubFolder2 |
| 9 | 7 | SubSubFolder1 |
内容的提问来源于stack exchange,提问作者Prashant Girase
相关产品推荐
相关产品推荐

