2015-12-18 193 views
0

我正在尋找填充我們公司結構的treelist。在我的數據庫中,我有一個表具有以下佈局位置從數據庫填充樹列表

PositionID - Integer for the position 
PositionText - Text for the position 
ReportsToID - Position ID that this position reports to. 

我想加載的位置,要positionID = 0(根級)的第一份報告,然後級聯加載每個位置從那裏起在填充一個TreeView,所以我就可以擁有財產以後這樣的:

-Position 1 
    -Position 3 
    -position 5 
    -Position 7 
    -Position 4 
    -Position 2 

就如何實現這一目標將是巨大的任何建議,甚至一些sudocode會幫助我在正確的軌道上。

編輯︰我能夠舒適與添加節點到我的樹形視圖,但我有點掛斷了是如何循環/遞歸搜索,以便我可以通過我的項目工作,並添加一切。林以某種方式想我需要添加我的第一個節點,看看是否有人報告該節點。如果有,請添加它們。然後對於下一級節點,看看是否有人向他們報告,然後繼續。 我可能有點卡住如何幹淨而高效地完成循環。

+0

這有幫助嗎?如果不是,請發佈具體問題。 https://support.microsoft.com/en-us/kb/320755 –

+0

謝謝,我知道如何填充樹視圖,可能應該更清楚我的問題。我想要幫助的是如何做循環/級聯來添加項目與他們的父節點/子節點。編寫代碼的最佳方法是什麼,以便我可以執行級聯並添加所需的項目? –

+0

對不起,我認爲鏈接顯示遞歸填充,但它沒有。一種方法是首先填充樹的根,然後使用這個:SELECT ReportsToID,PositionID,PositionText FROM Table ORDER BY ReportsToID,PositionID'。然後在每行的結果集中添加「ReportsToID」(父節點)節點(如果它不存在),然後將「PositionID」節點添加到樹中,直到處理完每一行。這是一種算法。 –

回答

0

我能夠解決這個問題,這是張貼在下面。這可能不是最優雅的,但它工作很快,似乎正常工作。任何對此的反饋都會很棒。

Private Sub LoadTreeList() 
    TreeView1.Nodes.Clear() 
    Dim dr() As System.Data.DataRow 
    dr = Me.PositionsDataSet.Positions.Select("ReportsToPositionID = 0") 
    'Populate the First Node 
    For Each Row In dr 
     TreeView1.Nodes.Add(Row("PositionID").ToString, Row("PositionText").ToString) 
     AddSubNodes(TreeView1.Nodes(Row("PositionID").ToString)) 
    Next 

End Sub 

Private Sub AddSubNodes(ByVal CurrentNode As TreeNode) 
    Dim dr() As System.Data.DataRow 
    dr = Me.PositionsDataSet.Positions.Select("ReportsToPositionID = " & CurrentNode.Name) 
    For Each Row In dr 
     Dim NewNode As TreeNode = CurrentNode.Nodes.Add(Row("PositionID").ToString, Row("PositionText").ToString) 
     Dim dr2() As System.Data.DataRow 
     dr2 = Me.PositionsDataSet.Positions.Select("ReportsToPositionID = " & Row("PositionID").ToString) 
     If dr2.Count > 0 Then 
      AddSubNodes(NewNode) 
     End If 
    Next 
End Sub 
+0

好的工作。這是另一種模式 - 用單獨的重複調用數據庫來填充每個節點。這可能是最慢的方法,但對於少量的節點,即幾百個),這可能是好的。它可能無法很好地擴展,所以如果您認爲樹會隨着時間而增長,請注意隨着時間的推移,性能會降低。 –

+0

謝謝,在這個階段只有50個左右的記錄,我不認爲它會在未來10年增長很多。 –

+0

很高興你找到了結果 - 你應該標記爲已回答。 –

1

使用此記錄:

SELECT ReportsToID, PositionID, PositionText 
FROM Table 
ORDER BY ReportsToID, PositionID 

然後

  1. 創建根節點(0)在你的樹
  2. 採取的第一行(這將需要有ReportsToID=0它)
  3. ReportsToID節點 下創建PositionID節點請注意,ReportsToID已經在步驟創建1或3
  4. 採取的下一行,然後轉到步驟3

具有順序意味着你總是纔去到一個新的水平創建一個完整的水平。

請注意,這裏有一個主要假設,那就是ID是增量式的。例如ReportsToID=5是不是ReportsToID=6

一個較低的水平,您可以使用,增加了一個「路徑」列中的更復雜的查詢避免這種情況。然後你在路上訂購。你需要一個CTE。

+0

謝謝。不幸的是,我的職位ID並不是增量的,因爲他們可能會在稍後的ID的報告中添加一個新的職位。 –

+0

確定該查詢需要更改爲提供可以排序的'路徑'字符串的CTE。這與@Shadow中的選項1一致答案 –

+0

下面是CTE的一個示例,它將迭代表變成也包含級別列的東西。如果你使用這個命令並按順序排序,那麼你可以保證你逐級填充樹。你做一個數據庫調用,而不是重複的:http://stackoverflow.com/questions/18106947/cte-recursion-to-get-tree-hierarchy –

0

TreeViews很棘手。 有兩種方法。

  1. 一次填滿所有樹。

優點:您曾經訪問過一次數據庫。代碼較少。

缺點:如果有很多數據,treeView會花一些時間來填充。

  1. 只填寫第一級,添加虛擬節點(表示虛假交叉符號),並在BeforeExpand查詢數據庫以填充節點。

優點:非常快。

缺點:在每個節點的第一個BeforeExpand上查詢數據庫。更多代碼。

所以,如果你只有一些節點來填補第一種方法。 但是,如果有嚴重的數據,第二個效果會更好。