好吧,这是其中一周。我无法弄清楚最简单的逻辑模式,它正在努力。
我有一个对象,我们称之为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,它返回一个具有明确定义级别的数据表:
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
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
我得到的是每个对象的列表,而不是树形结构。通过一些修改,我得到了一个级别,但是孩子的孩子被添加为父节点。
我的问题是 - 有人能看到有缺陷的逻辑吗?
我确信这是一个简单的解决办法,但无论出于何种原因我都无法掌握它。
感谢任何帮助,请不要犹豫,发表评论并要求进一步澄清。