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

Telerik C# RadTreeNode重复子节点问题解决咨询

问题描述

尝试获取指定路径的子节点时,成功获取但出现重复节点,推测是foreach循环次数导致该问题。以下是实现代码及界面重复节点现象截图:

实现代码

private void AgregarSubnodos(RadTreeNode parentNode, string carpetaPadre)
{
    try
    {
        // Abrir conexión SQL
        string cadenaConexionSQL = Global.GeneraConexionSQL();
        SqlConnection connection = new SqlConnection(cadenaConexionSQL);
        connection.Open();

        // Obtener las subcarpetas de la carpeta padre
        string[] subCarpetas = Directory.GetDirectories(carpetaPadre);

        foreach (string subCarpeta in subCarpetas)
        {
            string cadenaSQL = "SELECT carpeta_nodo FROM SEG_NODOS WHERE carpeta_nodo LIKE '" + subCarpeta + "%'";
            string mensajeVuelta = "";

            SqlDataReader dataReaderNodos;

            dataReaderNodos = Global.EjecutaComandoReaderSQL(cadenaConexionSQL, cadenaSQL, ref mensajeVuelta);
            if (dataReaderNodos.HasRows)
            {
                while (dataReaderNodos.Read())
                {
                    // Get the folder name of the current data reader row
                    string nombreCarpeta = dataReaderNodos.GetString(0);

                    // Create a new node for the subfolder
                    RadTreeNode subNode = new RadTreeNode();
                    subNode.Text = Path.GetFileName(subCarpeta);
                    subNode.Tag = subCarpeta;

                    // Node source
                    subNode.Font = new System.Drawing.Font("Segoe UI", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

                    // Add the node as a subnode of the parent node
                    parentNode.Nodes.Add(subNode);

                    // Recursively add subnodes for current subfolder
                    AgregarSubnodos(subNode, subCarpeta);

                }
            }
            dataReaderNodos.Close();
        }
        connection.Close();
    }
    catch (UnauthorizedAccessException)
    {
    }
    catch (Exception ex)
    {
        Global.SuperLog("Error al agregar subnodos: " + ex.Message);
    }
}

界面重复节点现象

应用界面重复节点显示


解决方案

问题根源

代码中存在核心逻辑错误:每读取一条SQL查询结果,就创建并添加一次相同的子节点。例如当SQL查询返回3条匹配subCarpeta的记录时,会循环3次,每次都生成一个文本、Tag完全一致的节点加到父节点下,最终导致重复。

修复步骤

  1. 调整节点创建逻辑:将节点的创建和添加操作移到while循环外部,每个subCarpeta只创建一次节点,无论SQL返回多少条记录。
  2. 修复SQL注入风险:原代码直接拼接字符串生成SQL语句,存在安全漏洞,改用参数化查询。
  3. 优化连接管理:使用using语句自动管理数据库连接和资源,避免泄漏。

修复后的代码

private void AgregarSubnodos(RadTreeNode parentNode, string carpetaPadre)
{
    try
    {
        string cadenaConexionSQL = Global.GeneraConexionSQL();
        string[] subCarpetas = Directory.GetDirectories(carpetaPadre);

        foreach (string subCarpeta in subCarpetas)
        {
            // 使用参数化查询避免SQL注入,根据业务需求调整匹配条件(示例为精确匹配)
            string cadenaSQL = "SELECT carpeta_nodo FROM SEG_NODOS WHERE carpeta_nodo = @CarpetaPath";
            string mensajeVuelta = "";

            // 用using自动管理连接、命令、阅读器的生命周期
            using (SqlConnection connection = new SqlConnection(cadenaConexionSQL))
            {
                connection.Open();
                using (SqlCommand cmd = new SqlCommand(cadenaSQL, connection))
                {
                    cmd.Parameters.AddWithValue("@CarpetaPath", subCarpeta);
                    using (SqlDataReader dataReaderNodos = cmd.ExecuteReader())
                    {
                        // 只要数据库中存在该文件夹的记录,就创建一次节点
                        if (dataReaderNodos.HasRows)
                        {
                            RadTreeNode subNode = new RadTreeNode();
                            subNode.Text = Path.GetFileName(subCarpeta);
                            subNode.Tag = subCarpeta;
                            subNode.Font = new System.Drawing.Font("Segoe UI", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                            
                            parentNode.Nodes.Add(subNode);
                            // 递归处理当前文件夹的子节点
                            AgregarSubnodos(subNode, subCarpeta);
                        }
                    }
                }
            }
        }
    }
    catch (UnauthorizedAccessException)
    {
        // 可添加日志记录,排查权限问题
    }
    catch (Exception ex)
    {
        Global.SuperLog("Error al agregar subnodos: " + ex.Message);
    }
}

额外说明

  • 如果业务需要匹配当前文件夹及其所有子目录的数据库记录,保留LIKE条件即可,但仍只需创建一次当前文件夹的节点,无需循环所有查询结果。
  • 原代码中重复打开/关闭数据库连接的操作会降低性能,using语句能自动释放资源,提升代码稳定性。

内容的提问来源于stack exchange,提问作者Hugo Jiménez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 02:15:04