【问题标题】:Generate list of parents-childs (recursive relationship) from Dataset从数据集中生成父子列表(递归关系)
【发布时间】:2013-07-25 09:16:23
【问题描述】:

我正在尝试建立一个具有递归关系的列表 (HTML)。数据在数据集中,但如果更容易,可以转换为数据表。

我不知道实现这一目标的最佳选择是什么。我正在考虑使用嵌套中继器。

这是数据:

__ID__ | __NAME__  | __PARENT__     | __LEVEL__ 
1      | Patrick   |                | 1           
2      | Mark      |                | 1
3      | Scott     | 2              | 2
4      | Jason     |                | 1
5      | Julian    |                | 1
6      | John      | 6              | 2
7      | Steve     |                | 1
8      | George    | 1              | 2
9      | Robert    | 1              | 2 
10     | Rodney    | 8              | 3

这里是我想要生成的输出

- Patrick [1]
  - George [8]
    - Rodney [10]
  - Robert [9]

- Mark [2]
  - Scott [3]

- Julian [5]
  - John [6]

- Jason [4]

- Steve [7]

【问题讨论】:

    标签: asp.net vb.net dataset recursive-datastructures


    【解决方案1】:

    最简单的方法是编写递归方法。它的操作方式将取决于您是希望该方法返回整个树结构列表,还是在读取数据时输出数据。如果您想在读取数据时输出数据,您的代码可能如下所示:

    Private Sub OutputTree(data As DataTable, parentId As String, indentationLevel As Integer)
        For Each row As DataRow In GetChildRows(parentId)
            OutputRow(row, indentationLevel)
            OutputTree(data, row("ID").ToString(), indentationLevel + 1)
        Next
    End Sub
    

    以上代码假设您还实现了一个名为GetChildRows 的方法,该方法返回包含给定父 ID 的所有行的列表。它还假设您有一个名为 OutputRow 的方法,它以给定的缩进级别输出给定的行。

    然后,您可以这样调用该方法:

    OutputTree(myDataTable, nothing, 0)
    

    如果您想构建并返回一个树形结构,这可以说是更好的方法,您的代码可能如下所示:

    Private Function BuildTreeNodes(data As DataTable, parentId As String) As List(Of MyTreeNode)
        Dim nodes As List(OfNew MyTreeNode)()
        For Each row As DataRow In GetChildRows(parentId)
            Dim node As New TreeNode()
            node.Row = row
            node.Children = BuildTreeNodes(data, row("ID").ToString())
            nodes.Add(node)
        Next
        Return node
    End Sub
    

    上面的代码假设你定义了一个MyTreeNode 类,看起来像这样:

    Public Class MyTreeNode
        Public Property Row As DataRow
        Public Property Children As List(Of MyTreeNode)
    End Class
    

    然后你可以这样调用方法:

    Dim rootLevelNodes As List(Of MyTreeNode) = BuildTreeNodes(myDataTable, Nothing)
    

    【讨论】:

    • 谢谢史蒂文。我最初计划使用 TreeView,但很快意识到 TreeView 控件的局限性。我不希望列表位于表格中,而是包含在特定的 HTML 标记(
      • )中。这就是为什么我认为使用嵌套中继器可以让我在输出列表时更加灵活。
    • 我对您的评论感到困惑。您是说我的示例出于某种原因对您不起作用,还是您只是提供了其他信息?
    • 我提到 TreeView 控件(树结构)在我的情况下不起作用。我想在
    • HTML 标记(嵌套的 HTML 列表)中输出列表的每个项目,而 TreeView 控件不允许我这样做。这就是为什么我认为唯一的其他选择是使用嵌套中继器。
  • 您是否误以为我的示例使用了TreeView 控件?
  • 【解决方案2】:

    如果您的父项的__PARENT__ 为空,这将起作用。

    private void TopItems(DataTable Data)
    {
        DataView view = new DataView(Data);
        view.RowFilter = "itemParent IS NULL";
    
        foreach (DataRowView row in view)
        {
            response.write("parent text: " + row["text"].ToString() + 
                     "parent id: " + row["id"].ToString();
            AddChildMenuItems(Data);
        }
    }
    
    
    //This code is used to recursively add child items by filtering by ParentID
    private void AddChildtems(DataTable Data)
    {
        DataView view = new DataView(Data);
        view.RowFilter = "itemParent=" + parentMenuItem.Value;
        foreach (DataRowView row in view)
        {
            response.write("child text: " + row["text"].ToString() + 
                     "child id: " + row["id"].ToString();
            AddChildtems(Data);
        }
    }
    

    【讨论】:

    • 感谢科比。识别父级(父级)的唯一方法是级别必须为 1。不能保证空值。我正在尝试以 HTML 格式输出列表(在标记代码中)。
    • 您可以使用 stringBuilder 而不是 response.write 来编写您的 html。也可以编辑view.RowFilter = "itemParent IS NULL";到您的过滤器。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签