从Dataset生成parent-childs列表(递归关系)

时间:2013-07-25 12:57:47

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

我正在尝试使用递归关系构建一个列表(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]

2 个答案:

答案 0 :(得分:2)

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

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)

答案 1 :(得分:0)

如果父项的__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);
    }
}