Pues no logró comprender exactamente en donde es que se repite, lo que te recomendaría es que hagas 2 consultas a la BD, una para llenar los nodos padre y luego para sus hijos
Podría ser así:
Código vb.net:
Ver originalPrivate Sub cargarNodos()
Using cn As New SqlConnection("Server=.;database=pruebas;integrated security=true")
'Consulta para nodos hijos
Using cmd As New SqlCommand("select m.nombre, f.nombre from formulario as f join menu as m on f.idmenu = m.idmenu", cn)
Using da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
'Crear datatable con los registros para los nodos hijo
da.Fill(ds, "hijo")
'Consulta nodos padres
cmd.CommandText = "select nombre from menu"
'Crear datatable con los registros para los nodos padre
da.Fill(ds, "padre")
'Bucle para llenar nodos padre
For Each dr As DataRow In ds.Tables("padre").Rows
Me.TreeView1.Nodes.Add(dr(0).ToString(), dr(0).ToString())
Next
'Bucle para llenar nodos hijo
For Each dr As DataRow In ds.Tables("hijo").Rows
Me.TreeView1.Nodes(dr(0).ToString()).Nodes.Add(dr(1).ToString())
Next
End Using
End Using
End Using
End Sub
Suponiendo que tengas 2 tablas, una llamada
menu con los campos
id y nombre mientras que la otra
formulario con sus campos
idform, nombre, idmenu.
Como ves primero hago una consulta en la que tengo los nodos hijos y luego una para los padres. El for each para los nodos padre lo agrego con su nombre y un key para luego poder determinar que nodo hijo le corresponde.
Espero no haberte confundido mucho XD