从表创建树结构

时间:2015-09-09 04:31:46

标签: vb.net recursion tree

好吧,这是其中一周。我无法弄清楚最简单的逻辑模式,它正在努力。

我有一个对象,我们称之为TreeNode:

对象:

Public Class TreeNode
    Public Key As Object
    Public Children As List(Of TreeNode)

    Public Sub AddToNode(parentNode As TreeNode)
        parentNode.Children.Add(Me)
    End Sub
End Class

足够简单 - 使用Key创建类的实例,如果它有子项,我可以使用AddToNode方法添加每个子项。

在我拥有的数据上。

我正在执行一个CTE,它返回一个具有明确定义级别的数据表:

CTE:

WITH CTE AS 
(
    SELECT Asset, Name, ParentAsset, [level] = 0 FROM database.schema.Asset WHERE Asset = WhateverAsset and (ParentAsset IS NULL)
UNION ALL 
    SELECT t.Asset, t.Name, t.ParentAsset, [level] = CTE.[level] + 1 FROM CTE 
INNER JOIN database.schema.Asset AS t 
    ON t.ParentAsset = CTE.Asset
) 
SELECT Asset, Name, ParentAsset, [level], CONVERT(BIT, 'FALSE') as Added FROM CTE ORDER BY [level]

这将返回一个如下所示的数据表:

数据:

2236|PARENT ASSET|NULL|0|0
2233|CHILD ASSET ONE|2236|1|0
2235|CHILD ASSET TWO|2236|1|0
2234|CHILD OF CHILD ASSET ONE|2235|1|0

现在我将此作为以下代码生成节点列表及其所有子节点作为节点列表等等。

递归函数

Private Sub GetChildren(dt As DataTable)

    For each row in dt.Rows
        If row.Item("Added") = False Then
            dim node as new Node
            node.Key = row.Item("Asset")

            parentAsset = F.GetNumber(row.Item("ParentAsset"))
            dim foundNode = FlattenAndFind(node)
            ....
            If IsNothing(foundNode) Then
               'Add to overall list
            Else
               node.AddToNode(foundNode)
            End If
            dim nextDt as New Datatable
            dim rows = dt.AsEnumerable.Where(function(suppRow) F.GetNumber(suppRow.Item("ParentAsset")) = parentAsset)
            if rows.Any Then 
                dtt = rows.CopyToDataTable()
            End If
            GetChildreen(nextDt)
        Next
End Sub

FlattenAndFilter(感谢SO上有人为此功能):

Private Function FlattenAndFilter(source As Node) as IEnumerable(Of Node)
    Dim l As New List(Of Node)
    If source.Key = parentAsset Then l.Add(source)
    If l.Count = 1 Then
        Return l.Concat(source.Children.SelectMany(Function(child) FlattenAndFilter(child)))
    Else
        Return Nothing
    End If
End Function

我得到的是每个对象的列表,而不是树形结构。通过一些修改,我得到了一个级别,但是孩子的孩子被添加为父节点。

我的问题是 - 有人能看到有缺陷的逻辑吗?

我确信这是一个简单的解决办法,但无论出于何种原因我都无法掌握它。

感谢任何帮助,请不要犹豫,发表评论并要求进一步澄清。

0 个答案:

没有答案