显示继承人结构树ASP C#/Stringbuilder/递归

显示继承人结构树ASP C#/Stringbuilder/递归,c#,recursion,tree,hierarchy,stringbuilder,C#,Recursion,Tree,Hierarchy,Stringbuilder,我已经做了一些搜索,并找到了任何类似于我的情况,并将感谢另一双眼睛给我一些建议 我的任务是显示数据树,并制定了创建此表结构的存储过程: 它应该包含我需要的所有内容,包括级别、父级和文件夹id[文档\u类别\u id] 计划是使用以下HTML结构显示数据 <div class="parent">Folder 1</div> <div class="sublevel"> <div class="subfolder">Folde

我已经做了一些搜索,并找到了任何类似于我的情况,并将感谢另一双眼睛给我一些建议

我的任务是显示数据树,并制定了创建此表结构的存储过程:

它应该包含我需要的所有内容,包括级别、父级和文件夹id[文档\u类别\u id]

计划是使用以下HTML结构显示数据

<div class="parent">Folder 1</div>
    <div class="sublevel">
        <div class="subfolder">Folder 1 Subfolder</div>
             <div class="sublevel">
                 <div class="subfolder">Folder 1 Subfolder Level 2</div>
              </div>

<div class="parent">Folder 2</div>
    <div class="sublevel">
        <div class="subfolder">Subfolder 1</div>
        <div class="subfolder">Subfolder 2</div>
    </div>
文件夹1
文件夹1子文件夹
文件夹1子文件夹级别2
文件夹2
子文件夹1
子文件夹2
sublevel类有一个边距,用于创建缩进,随后的子节点插入会增加标识

这是C代码。诚然,我对递归没有太多经验,我很想学习如何解决这个问题。我在这篇文章之后很轻松地对此进行了建模:但你会发现有一些不同之处

SqlConnection connection = null;
        connection = new SqlConnection(ConfigurationData.databaseConnectionString);
        SqlCommand command = new SqlCommand("myconnectionstring", connection);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.AddWithValue("@myparameter", myparameter);

        try {
            connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            int rowcount = 0;
            int count = reader.FieldCount;

            while (reader.Read()) {

                _folderCategoryId = (int)reader["document_category_id"];
                if (!DBNull.Value.Equals(reader["parent_category_id"])) {
                    _folderParentCategoryId = (int)reader["parent_category_id"];
                }
                if (DBNull.Value.Equals(reader["parent_category_id"])) {
                    _folderParentCategoryId = 0;
                }
                _level = (int)reader["level"];
                _folderName = (string)reader["name"];
                _folderDescription = (string)reader["description"];
                rowcount = rowcount + 1;
                //parent catgories get their own closed "parent" class div


                if (_level == 0) {
                    _displayString.Append("<div class=\"parent\" >");
                    _displayString.Append(_folderName);
                    _displayString.Append("</div>");
                }

                for (int i = 1; i <= _level; i++) {
                    WriteNode(reader, _displayString);
                }
                _displayString.Append("</div>");

            }
            if (rowcount < 1) {
                _displayString.Clear();
                _displayString.Append("No Folders");
            }
        }
        catch {
            _displayString.Clear();
            _displayString.Append("Error Retreiving Documents List");
        }
            finally {
                if (connection != null) {
                    connection.Close();
                }
            }
    }
    // recursively write out each node
    public static void WriteNode(SqlDataReader reader, StringBuilder _displayString) {


        // find children rows...
        int level = (int)reader["level"];
        string name = (string)reader["name"];


        if (level >= 1) {
            _displayString.Append("</div>");
            _displayString.Append("<div class=\"sublevel\">");
            _displayString.Append(name);

        }

    }
SqlConnection=null;
连接=新的SqlConnection(ConfigurationData.databaseConnectionString);
SqlCommand=newsqlcommand(“myconnectionstring”,connection);
command.CommandType=CommandType.storedProcess;
command.Parameters.AddWithValue(“@myparameter”,myparameter);
试一试{
connection.Open();
SqlDataReader=command.ExecuteReader();
int rowcount=0;
int count=reader.FieldCount;
while(reader.Read()){
_folderCategoryId=(int)读卡器[“文档类别id”];
如果(!DBNull.Value.Equals(读卡器[“父类\类别\ id”])){
_folderParentCategoryId=(int)读卡器[“父类别id”];
}
if(DBNull.Value.Equals(读卡器[“父类\类别\ id”])){
_folderParentCategoryId=0;
}
_级别=(int)读卡器[“级别”];
_folderName=(字符串)读取器[“名称”];
_folderDescription=(字符串)读取器[“description”];
rowcount=rowcount+1;
//父类别有自己封闭的“父”类div
如果(_level==0){
_displayString.Append(“”);
_displayString.Append(_folderName);
_displayString.Append(“”);
}
对于(int i=1;i=1){
_displayString.Append(“”);
_displayString.Append(“”);
_displayString.Append(名称);
}
}
所以,我知道这里显然有问题。我一直在弄乱它,它有点工作,但主要是不可靠的-通常有未关闭的div,或太多的结束div标签,取决于孩子的数量

很可能是对WriteNode方法的调用-我应该在这里检查以前的folderid值吗?长度足够长吗?我应该在这里关闭一个div吗


任何指针都将不胜感激。

几天前就解决了这个问题。我使用的数据集不需要递归

if (_level > prevLevel) { //must be a child
                        _displayString.Append("<div class=");
                        _displayString.Append("\"subfolder\" >");
                        formatClickString(_displayString, _folderCategoryId, _uploadVisibility, _folderName);
                    }
                if (_level < prevLevel) { //start new level
                        for (int i = 0; i <= prevLevel; i++) {
                            _displayString.Append("</div>");
                        }
                    _displayString.Append("<div class=\"subfolder\" >");
                    formatClickString(_displayString, _folderCategoryId, _uploadVisibility, _folderName);

                    }
                if (_level == prevLevel) { //is child and own line
                    _displayString.Append("</div>");
                    _displayString.Append("<div class=\"subfolder\" >");
                    formatClickString(_displayString, _folderCategoryId, _uploadVisibility, _folderName);

                    }
                prevLevel = _level;
if(_level>prevLevel){//必须是子级
_displayString.Append(“”);
formatClickString(_displayString、_folderCategoryId、_uploadVisibility、_folderName);
}
如果(_level