从mysql内容分层填充treeview

从mysql内容分层填充treeview,mysql,vb.net,treeview,Mysql,Vb.net,Treeview,我正在尝试构建一个使用mysql数据库中的数据填充的树视图。 通常我会说这不会有问题,除非我允许用户控制根元素、父元素和子元素(数量可能不同,命名可能不稳定) 示例:假设数据库显示employees,但用户拥有多个公司和多个部门(可以添加或删除),如下所示 Company ABC Accounting Employee A Employee B Marketing Employee D Employee F Operations Employe

我正在尝试构建一个使用mysql数据库中的数据填充的树视图。 通常我会说这不会有问题,除非我允许用户控制根元素、父元素和子元素(数量可能不同,命名可能不稳定)

示例:假设数据库显示employees,但用户拥有多个公司和多个部门(可以添加或删除),如下所示

Company ABC
  Accounting
    Employee A
    Employee B
  Marketing
    Employee D
    Employee F
  Operations
    Employee Z
  Human Resources
    Employee N
Company 123
  Road Crew
    Employee 1
    Employee 2
    Employee 3
  Dispatcher
    Employee 5
我为此提出的方法是执行running for语句,并确定该项是什么类别(根、父项或子项)。然后运行一条语句将其适当地添加到treeview、rootitem或parentitem

Dim con As New MySqlConnection()
Dim adptr As New MySqlDataAdapter
Dim pagers As New DataTable
Dim Roots() As TreeNode
Dim Parents() As TreeNode
Dim Children() As TreeNode



        con.ConnectionString = "server=localhost;" _
& "user id=*****;" _
& "password=****;" _
& "database=****"
    adptr = New MySqlDataAdapter("SELECT * FROM pagers", con)
    Try
        adptr.Fill(pagers)
    Catch err As Exception
        Dim strError As String = "Exception: & err.ToString()"
    End Try
    If pagers.Rows.Count > 0 Then
        For pop As Integer = 0 To pagers.Rows.Count - 1
            If pendrun.Rows(pop)("type") = "root" Then
                Dim curid As Integer = pendrun.Rows(pop)("id")
                Dim roots(curid) As TreeNode = TreeView1.Nodes.Add(pendrun.Rows(pop)("name"))
            End If
            If pendrun.Rows(pop)("type") = "parent" Then
                Dim curid As Integer = pendrun.Rows(pop)("id")
                Dim rootid As Integer = pendrun.Rows(pop)("rootid")
                Dim Parents(curid) As TreeNode = Roots(rootid).Nodes.Add(pendrun.Rows(pop)("name"))
            End If
            If pendrun.Rows(pop)("type") = "child" Then
                Dim curid As Integer = pendrun.Rows(pop)("id")
                Dim parentid As Integer = pendrun.Rows(pop)("parentid")
                Dim Children(curid) As TreeNode = Parents(parentid).Nodes.Add(pendrun.Rows(pop)("name"))
            End If
        Next
    End If
这显然有两个问题

问题#1是软件可能在创建父项之前到达子项,这可能会导致错误

可能的解决方案#1-我可以分别调用mysql数据库3次,然后使用While type=“root”then=“parent”then=“child”,这确实不理想

问题#2是VB.net不允许我创建treenode数组,至少在指定方法时不允许

可能的解决方案2——我不知道

我相信这是一个以前遇到过的问题——有人知道解决这个问题的更合适的方法吗

表示例:

 id |    name    | type | rootid | parentid
 1   Company ABC   root    Null      Null
 2   Accounting   parent    1        Null
 3   Employee A   child     1         2
 4   Employee B   child     1         2
 5    Marketing   parent    1        Null
 6   Employee D   child     1         5
 7   Employee F   child     1         5
 8   Marketing    parent    1        Null
 ...
如果你愿意,我会继续建造更多的桌子

检索代码:

    con.ConnectionString = "server=****;" _
& "user id=****;" _
& "password=****;" _
& "database=***"
    adptr = New MySqlDataAdapter("SELECT * FROM pagers", con)
    Try
        adptr.Fill(pagers)
        pagers.PrimaryKey = New DataColumn() {pagers.Columns("id")}
    Catch err As Exception
        Dim strError As String = "Exception: & err.ToString()"
    End Try
    If pagers.Rows.Count > 0 Then
        For pop As Integer = 0 To pagers.Rows.Count - 1
            If pagers.Rows(pop)("type") = "root" Then
                LoadRoot(Nothing, pagers.Rows(pop)("id"))
            End If

        Next
    End If

我不能在评论中这样说。 为了使用parentid列控制treeview的布局,我在表格中的填充方式略有不同:

  • 1,“公司ABC”,“根”,空,空
  • 2,“会计”,“母公司”,1,1
  • 3,“雇员A”,“子女”,1,2
  • 4,“雇员B”,“子女”,1,2
  • 5,“营销”、“家长”,1,1
  • 6,“雇员D”,“子女”,1,5
  • 7,“雇员F”,“子女”,1,5
  • 8,“市场营销”,“家长”,1,1

  • 9,“公司123”,“根”,空,空

  • 10,“道路工作人员”,“家长”,9,9
  • 11,“雇员1”,“子女”,9,10
  • 12,“雇员2”,“子女”,9,10
  • 13、“雇员3”、“子女”9、10
  • 14,“调度员”,“家长”,9,9
  • 15、“雇员5”、“子女”9、14
然后将所需根的id传递给此函数:

私有Sub LoadRoot(ByValPar为树型,ByValid为整数) 作为树烯的二甲基亚硝胺 按数据行显示

    oRow = mTbl.Rows.Find(New Object() {Id})
    If Not oRow Is Nothing Then
        If Par Is Nothing Then
            oNode = tv.Nodes.Add(oRow.Item("name").ToString)
        Else
            oNode = Par.Nodes.Add(oRow.Item("name").ToString)
        End If
        For Each oRow In mTbl.Select("parentid = " & Id.ToString)
            LoadRoot(oNode, CInt(oRow.Item("id")))
        Next
    End If

End Sub

在您已保存数据的表数中..请提供表和架构..表示例已添加到问题中。假设用户随后决定删除#11“employee 1”是否会导致错误该示例仍然有效。如果我删除Road Crew,那么它将加载公司123,而不加载Road Crew,但会有一些孤立的员工记录。加载树似乎没问题,您只需要控制添加和删除如何保持数据干净。我试图理解这里的代码-因此对于添加id 11,我将运行LoadRoot(?,11)what in???另外,在添加根级别时,插槽中只包含null值sloadroot(Nothing,11)。对我来说,这是员工1的id,所以这就是进入树的全部内容。LoadRoot(无,10)将显示整个道路工作人员。根级别的项只能为Null。LoadRoot的第一个参数实际上只是用于它需要进行的递归调用。当Command对象获取表时,您不会得到主键。您需要自己设置它
DataTable.PrimaryKey=New DataColumn(){DataTable.Columns(“id”)}
这是有意义的,因为您实际上正在获取一个记录集,并且它可能没有唯一的值。