已经添加了具有相同键 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说“已经添加了一个具有相同密钥的项目”。