You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归构建文档树出现重复节点问题的排查与修复求助

文档递归依赖树生成问题修复

问题描述

我有一批基于其他文档生成的文档,尝试通过递归查找它们依赖的源文档,但当前实现存在问题:所有节点都重复合并在一起,无法生成正确的层级结构,期望生成层级分明的文档树结构。核心传递参数为文档类型和子元素列表。

当前实现代码

递归填充方法

public async Task<List<DocumentTreeItem>> FillRecursionTree(Guid documentId, string documentPresentationName, List<DocumentTreeItem> treeItems, Type documentType)
{
    await FillRecursionTree(documentId, documentPresentationName, treeItems, documentType);
 
    return treeItems;

    async Task FillRecursionTree(Guid childrenId, string childrenIdDocumentPresentationName, List<DocumentTreeItem> childrenIdTreeItems, Type childrenIdDocumentType)
    {
        var currentNode = new DocumentTreeItem(documentPresentationName, childrenIdDocumentType, childrenIdTreeItems)
        {
            Id = childrenId,
            DocumentPresentationName = childrenIdDocumentPresentationName,
            TypeDocument = childrenIdDocumentType
        };
        childrenIdTreeItems.Add(currentNode);

        var customerInvoices = await GetBaseCustomerInvoiceDocuments(childrenId);
        foreach (var customerInvoice in customerInvoices)
        {
            childrenIdDocumentType = customerInvoice.GetType();
            await FillRecursionTree(customerInvoice.Id, customerInvoice.DocumentPresentationName, currentNode.Childrens, childrenIdDocumentType);
        }
    }
}

节点实体类

public Guid Id { get; set; }
public string? DocumentPresentationName { get; set; }
public Type TypeDocument { get; set; }

public List<DocumentTreeItem> Childrens { get; set; } = new List<DocumentTreeItem>();

public DocumentTreeItem(string documentPresentationName, Type typeDocument, List<DocumentTreeItem> children = null)
{
    DocumentPresentationName = documentPresentationName;
    TypeDocument = typeDocument;
    if (children != null)
        Children.AddRange(children);
}

public List<DocumentTreeItem> Children
{
    get
    {
        return Childrens;
    }
}

问题分析

  1. 构造函数参数错误:创建currentNode时,将父节点的列表childrenIdTreeItems传入构造函数,导致当前节点的Children直接引用父列表,后续添加节点时会全部混入同一集合,无法形成层级。
  2. 初始化逻辑混淆:构造函数中把传入的children添加到自身Children,同时又把currentNode添加到父列表childrenIdTreeItems,形成循环引用,进一步破坏层级结构。
  3. 命名不统一:实体类中字段Childrens与属性Children命名冗余,增加代码混淆风险。

修复方案

修正后的节点实体类

统一命名,简化子节点集合的定义:

public Guid Id { get; set; }
public string? DocumentPresentationName { get; set; }
public Type TypeDocument { get; set; }

public List<DocumentTreeItem> Children { get; set; } = new List<DocumentTreeItem>();

public DocumentTreeItem(string documentPresentationName, Type typeDocument)
{
    DocumentPresentationName = documentPresentationName;
    TypeDocument = typeDocument;
}

修正后的递归填充方法

去掉构造函数的子节点参数,确保每个节点的子节点使用自身独立的Children集合,同时修正节点名称的赋值错误:

public async Task<List<DocumentTreeItem>> FillRecursionTree(Guid documentId, string documentPresentationName, Type documentType)
{
    var rootTree = new List<DocumentTreeItem>();
    await FillRecursionTreeInternal(documentId, documentPresentationName, rootTree, documentType);
    return rootTree;

    async Task FillRecursionTreeInternal(Guid nodeId, string nodeName, List<DocumentTreeItem> parentList, Type nodeType)
    {
        // 创建当前节点,子节点集合默认初始化
        var currentNode = new DocumentTreeItem(nodeName, nodeType)
        {
            Id = nodeId,
            DocumentPresentationName = nodeName,
            TypeDocument = nodeType
        };
        // 将当前节点添加到父节点的子集合中
        parentList.Add(currentNode);

        // 递归查找当前节点的依赖文档
        var dependentDocuments = await GetBaseCustomerInvoiceDocuments(nodeId);
        foreach (var doc in dependentDocuments)
        {
            await FillRecursionTreeInternal(doc.Id, doc.DocumentPresentationName, currentNode.Children, doc.GetType());
        }
    }
}

关键修复点说明

  • 移除了实体类构造函数的子节点参数,避免错误引用父集合;
  • 递归方法改为内部独立方法,初始调用时创建根列表,确保根节点正确挂载;
  • 创建当前节点时使用自身的Children集合传递给下一层递归,保证层级嵌套;
  • 修正了节点名称赋值错误(原代码中错误使用外层方法的documentPresentationName而非当前节点的nodeName)。

内容的提问来源于stack exchange,提问作者hans fridrech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 04:10:32