已经添加了具有相同键 TREEVIEW vb.net 和 sql server 的项目

Posted

技术标签:

【中文标题】已经添加了具有相同键 TREEVIEW vb.net 和 sql server 的项目【英文标题】:with already added an item with the same key TREEVIEW vb.net and sql server 【发布时间】:2021-04-05 15:49:59 【问题描述】:

我有这个错误,我不确定是什么原因造成的:

已添加具有相同键的元素

我在树形视图中显示数据如下:DEPARTMENT / PROVINCE / DISTRICT 用 Visual Basic 制作的附件代码:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim conexaoSQLServer As SqlConnection = Nothing
    Dim cmd As SqlCommand
    Dim da As New SqlDataAdapter
    Dim ds As New DataSet


    Dim strCon As String = "Data Source = SOPORTE-ERP\SQLEXPRESS; Initial Catalog = prueba; Integrated Security = True"
        'define a consulta para obter as tabelas e suas colunas
    Dim sqlConsulta As String = "SELECT DESCRIPCION AS nodeText,'DEPA' + CAST(IDDEPARTAMENTO AS VARCHAR) AS nodeKey,''AS nodeParentKey FROM DEPARTAMENTO " +
        "UNION ALL SELECT DESCRIPCION AS nodeText,'PROV' + CAST(IDPROVINCIA AS VARCHAR) AS nodeKey,'DEPA' + CAST(IDDEPARTAMENTO AS VARCHAR) AS nodeParentKey " +
        "FROM PROVINCIAS UNION SELECT DESCRIPCION AS nodeText,'DIST' + CAST(IDUBIGEO AS VARCHAR) AS nodeKey," +
         "'PROV' + CAST(IDPROVINCIA AS VARCHAR) AS nodeParentKey FROM UBIGEO"


    Try
        'define e abre a conexão com o SQL Server
        conexaoSQLServer = New SqlConnection(strCon)
        conexaoSQLServer.Open()

        'atribui o comando usado na conexão
        cmd = New SqlCommand(sqlConsulta, conexaoSQLServer)
        da.SelectCommand = cmd

        'preenche o dataset
        da.Fill(ds, "DATOS_SISTEMAS")

        'Helper dictionaries
        Dim nodes2 As New Dictionary(Of String, TreeNode) 'Holds the nodes based on their key values
        Dim nodeParents As New Dictionary(Of String, String) 'Holds the parent keys of child nodes

        'Create nodes from data
        For Each row As DataRow In ds.Tables("DATOS_SISTEMAS").Rows
            Dim nodeText2 As String = row.Field(Of String)("nodeText")
            Dim nodeKey2 As String = row.Field(Of String)("nodeKey")
            Dim nodeParentKey2 As String = row.Field(Of String)("nodeParentKey")

            nodes2.Add(nodeKey2, New TreeNode(nodeText2))

            If Not String.IsNullOrEmpty(nodeParentKey2) Then
                nodeParents.Add(nodeKey2, nodeParentKey2)
            End If
        Next

        'Add nodes to treeview (and resolve parents)
        For Each kvp In nodes2
            Dim node1 As TreeNode = kvp.Value
            Dim nodeKeys1 As String = kvp.Key
            Dim nodeParentKeys1 As String = Nothing

            If nodeParents.TryGetValue(nodeKeys1, nodeParentKeys1) Then
                'Child node
                Dim parentNode As TreeNode = nodes2(nodeParentKeys1)
                parentNode.Nodes.Add(node1)
            Else
                'Root node
                TreeView1.Nodes.Add(node1)

            End If
        Next
    Catch ex As Exception
        MessageBox.Show("error when performing this operation:  " & ex.Message)
        Exit Sub
    Finally
       'libera os recursos da conexão usada
        conexaoSQLServer.Close()
        conexaoSQLServer.Dispose()
        conexaoSQLServer = Nothing
    End Try

End Sub

我验证了每个表的 ID 字段都是唯一的并且是自动递增的。这似乎是字典的错误。我做错了什么?

【问题讨论】:

调用 .Close().Dispose() 并设置为 Nothing 是从 vb6/vbscript 时代遗留下来的,不再需要或没有帮助,并且在极少数情况下可能会产生积极的危害. .Dispose() 对 VB.Net 来说就足够了 假设您已经单步执行了代码并查看了断点或错误处的错误值,那么有问题的值是什么?错误发生在哪一行? nodes2.Add(nodeKey2, New TreeNode(nodeText2)) ? parentNode.Nodes.Add(node1)?请提供更详细的信息。 【参考方案1】:

我怀疑缺少Tree1.Nodes.Clear() 是主要问题,但可能还有其他问题,问题是缺少一些重要信息(数据!),并且代码以过时的风格编写。结果是我不得不进行现代化改造,因为我去寻找这么多东西,我可能仍然遗漏了一些东西。见下文,并记下我添加的表扬:

'Separate DB access from event code!
Friend Module DB
    Private connectString As String = "Data Source = SOPORTE-ERP\SQLEXPRESS; Initial Catalog = prueba; Integrated Security = True"

    Public Function GetTreeNodeData() As DataTable
        'multi-line string literals work now
        Dim sql As String = "
SELECT * 
FROM (
    SELECT DESCRIPCION AS nodeText,'DEPA' + CAST(IDDEPARTAMENTO AS VARCHAR) AS nodeKey,''AS nodeParentKey 
    FROM DEPARTAMENTO
UNION ALL 
    SELECT DESCRIPCION AS nodeText,'PROV' + CAST(IDPROVINCIA AS VARCHAR) AS nodeKey,'DEPA' + CAST(IDDEPARTAMENTO AS VARCHAR) AS nodeParentKey
    FROM PROVINCIAS 
UNION 
    SELECT DESCRIPCION AS nodeText,'DIST' + CAST(IDUBIGEO AS VARCHAR) AS nodeKey,'PROV' + CAST(IDPROVINCIA AS VARCHAR) AS nodeParentKey 
    FROM UBIGEO
) t
ORDER BY t.NodeParentKey, t.NodeKey, t.NodeText"

        Dim ds As New DataSet
        Using cn As New SqlConnection(connectString), _
              cmd As New SqlCommand(sql, cn), _
              da As New SqlDataAdapter(cmd)

            'preenche o dataset
            da.Fill(ds, "DATOS_SISTEMAS") '.Fill() opens and closes automatically
        End Using 'End Using closes the connection, **even if an exception is thrown!**
        Return ds.Tables("DATOS_SISTEMAS")
    End Function
End Module


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click   
    'Limit the scope of each try/catch, so the error message can be more meaningful/helpful
    Dim nodeRecords As DataTable
    Try
        'Create nodes from data
        nodeRecords = DB.GetTreeNodeData()
    Catch ex As Exception
        MessageBox.Show($"Error performing database operation:vbCrLfex.Message")
        Exit Sub
    End Try

    Dim nodes As New Dictionary(Of String, TreeNode)
    Try
        For Each row As DataRow In nodeRecords.Rows
            Dim nodeKey As String = row.Field(Of String)("nodeKey")
            Dim nodeText As String = row.Field(Of String)("nodeText")
            Dim parentKey As String = row.Field(Of String)("nodeParentKey")

            If Not nodes.ContainsKey(parentKey) Then
                nodes.Add(parentKey, new TreeNode())
            End If

            If nodes.ContainsKey(nodeKey) Then
                nodes(nodeKey).Text = nodeText
                nodes(parentKey).Nodes.Add(nodes(nodeKey)) 'we know the parent exists, because we just created it if it was missing               
            Else
                Dim node As New TreeNode(nodeText)
                nodes(parentKey).Nodes.Add(node)
                nodes.Add(nodeKey, node)
            End If

        Next row
    Catch ex As Exception
        MessageBox.Show($"Error building tree:vbCrLfex.Message")
        Exit Sub
    End Try

    TreeView1.SuspendLayout() 'suspend/resume layout avoids flickering as control is updated
    TreeView1.Nodes.Clear() 'I suspect missing this is your main problem
    For Each kvp As KeyValuePair(Of String, TreeNode) In nodes.Where(Function (n) n.Parent Is Nothing)
        TreeView1.Nodes.Add(node1)
    Next kvp
    TreeView1.ResumeLayout()
End Sub

【讨论】:

您好,亲爱的,我在这一行有 2 个错误:nodes (nodeKey) .Parent = nodes (parentKey) ----- 告诉我“Parent 属性是 ReadOnly”,另一个在这部分:在 nodes.Where (Function (n) n. Parent is nothing) - 重载解析错误,因为没有“Where”函数 第二次,确保您在顶部有一个Imports System.Linq 好的,已更新以修复第一个问题。

以上是关于已经添加了具有相同键 TREEVIEW vb.net 和 sql server 的项目的主要内容,如果未能解决你的问题,请参考以下文章

工作区出现故障,TFS说“已经添加了一个具有相同密钥的项目”。

atomic query-仅当没有其他具有相同键[duplicate]的文档时才添加新文档

已添加具有相同键的实体框架核心 3.1.6 项

已添加具有相同键的项目

GET 调用:已添加具有相同密钥的项目。键:标识

带有连接表的 MySQL 外键约束(具有相同外键约束时出错)