C# 递归实现无限层级TreeView树形对象的父子节点存储
现有实现的问题
- 硬编码三层循环,每多一层嵌套就需要手动加一层循环,完全无法适配任意层级的树结构
- 子节点赋值逻辑错误:第二层、第三层的数据库实体的
Id、Name错用了顶层viewModel的属性,没有读取当前遍历的子节点自身的字段,最终所有子节点都会和顶层节点数据完全一致
递归实现代码
public bool SaveOrUpdateTreeView(TreeView topViewModel) { // 从顶层节点开始递归持久化,顶层节点的父Id直接用视图模型传入的值 RecursiveSaveNode(topViewModel, topViewModel.ParentId); return true; } /// <summary> /// 递归保存单个节点及其所有子节点 /// </summary> /// <param name="currentNode">当前要持久化的树节点</param> /// <param name="parentDbId">父节点在数据库中的实际主键</param> private void RecursiveSaveNode(TreeView currentNode, int parentDbId) { // 转换为数据库实体 var dbEntity = new TreeViewDb { Id = currentNode.Id, // 保留原有Id支持更新,新增节点Id为0时由仓储层处理自增逻辑 ParentId = parentDbId, Name = currentNode.Name }; // 保存当前节点,拿到自身在数据库里的主键 var currentNodeId = _dataRepository.SaveOrUpdateTreeView(dbEntity); // 遍历所有子节点,把当前节点的数据库主键作为子节点的父Id递归保存 foreach (var child in currentNode.Children) { RecursiveSaveNode(child, currentNodeId); } }
逻辑说明
- 不需要手动嵌套多层循环,不管树嵌套多少层,只要节点在视图模型的
Children集合里,都会被递归遍历处理 - 子节点的
ParentId统一传入父节点已经持久化后的真实主键,避免新增节点时临时Id和数据库生成的自增Id不匹配的问题 - 完全兼容原有仓储的
SaveOrUpdateTreeView逻辑,无需修改仓储层代码
内容的提问来源于stack exchange,提问作者mnu-nasir
相关产品推荐
相关产品推荐

