Заполнение трехуровневого древовидного представления кодом VB.NET таблицы SQL Server

Я успешно запрограммировал заполнение двухуровневого объекта древовидного представления, как показано ниже:

Dim query As String = "SELECT GrandLedgers, Ledgers FROM TrvBook WHERE ID = @OwnerID"

Using con = New SqlConnection(ConString)
    Using cmd = New SqlCommand(query, con)
        cmd.Parameters.Add(New SqlParameter("@OwnerID", My.Settings.OwnerID))

        con.Open()

        Dim dt As SqlDataReader = cmd.ExecuteReader
        Dim gl, l As String
        Dim name1 As String = ""

        While dt.Read
            Dim node1 As New TreeNode
            gl = dt.Item(0).ToString
            l = dt.Item(1).ToString

            If name1 = gl Then
                TreeViewBook.SelectedNode.Nodes.Add(0)
            Else
                name1 = gl
                node1 = TreeViewBook.Nodes.Add(gl)
                TreeViewBook.SelectedNode = node1
                TreeViewBook.SelectedNode.Nodes.Add(0)
            End If
        End While
    End Using
End Using

TreeViewBook.ExpandAll()

Я попытался добавить третий уровень к этому древовидному представлению с помощью добавленного столбца Persons, как показано в этом запросе:

Dim query As String = "SELECT GrandLedgers, Ledgers, Persons FROM TrvBook WHERE ID = @OwnerID"

но мне это не удалось.

Выкладываю исходный код для внесения поправок.

Пожалуйста, дайте мне ваш измененный код для создания трехуровневого древовидного представления.

Меня удивляет, что два первых уровня вообще успешны, потому что вы предполагаете, что дочерние элементы, соответствующие родителю, появляются после родителя; однако в вашем операторе SELECT нет ORDER BY, и поэтому порядок записей не гарантируется. Кроме того, мне неясно, как связаны эти три уровня. Можете ли вы привести примеры данных и ожидаемый результат?

Olivier Jacot-Descombes 06.04.2024 16:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть ряд вещей, которые вам следует изменить. Во-первых, как предложено в комментариях, вам следует отсортировать результаты. Таким образом, вы будете знать, что все значения, одинаковые в определенном столбце, будут сгруппированы. Вам также не следует добавлять узлы в дерево по мере их создания. Каждый раз, когда вы создаете несколько элементов для такого элемента управления, первым вариантом должно быть сначала создать элементы, а затем в конце добавить их все в один пакет. Вот один из вариантов сделать то, что вы хотите:

Dim query = "SELECT Column1, Column2, Column3
             FROM Table1 Where Id = @Id
             ORDER BY Columnn1, Column2"
Dim nodes As New List(Of TreeNode)

Using connection As New SqlConnection(connectionString),
      command As New SqlCommand(query, connection)
    command.Parameters.Add("@Id", SqlDbType.Int).Value = id

    Dim parentNode As TreeNode = Nothing
    Dim childNode As TreeNode = Nothing

    Using reader = command.ExecuteReader()
        While reader.Read()
            Dim parent = reader.GetString(reader.GetOrdinal("Column1"))
            Dim child = reader.GetString(reader.GetOrdinal("Column2"))
            Dim grandchild = reader.GetString(reader.GetOrdinal("Column3"))

            If parent <> parentNode?.Text Then
                'Either there is no parent node or the parent value has changed so create a new parent node.
                parentNode = New TreeNode(parent)
                nodes.Add(parentNode)
                childNode = Nothing
            End If

            If child <> childNode?.Text Then
                'Either there is no child node or the child value has changed so create a new child node.
                childNode = New TreeNode(child)
                parentNode.Nodes.Add(childNode)
            End If

            childNode.Nodes.Add(New TreeNode(grandchild))
        End While
    End Using
End Using

'Add all nodes to the tree in a single batch.
TreeView1.Nodes.AddRange(nodes.ToArray())

Еще один небольшой момент — это способ добавления параметра запроса. Этот:

cmd.Parameters.Add(New SqlParameter("@OwnerID", My.Settings.OwnerID))

можно было бы более кратко записать так:

cmd.Parameters.AddWithValue("@OwnerID", My.Settings.OwnerID)

и это плохо. Вероятно, в этом случае это сработает, но вы полагаетесь на то, что система определит правильный тип данных на основе значения, и это будет работать не во всех случаях. Знаете, в каких случаях это не сработает? Если вы не сделаете этого таким образом, вам не о чем беспокоиться. Сделайте это так, как я сделал в приведенном выше примере, т. е. явно укажите тип данных, и вы не ошибетесь. Для типов данных переменной длины вы также должны указать длину, например.

command.Parameters.Add("@Name", SqlDbType.VarChar, 50).Value = name

Теперь я понимаю форму данных ОП. Сначала я предположил, что это представляет собой иерархическую структуру, связывающую дочернюю запись с родительской записью через ключ. Но, увидев этот идеальный ответ, я понимаю, что данные денормализованы и представляют иерархию «визуально».

Olivier Jacot-Descombes 07.04.2024 17:16

Спасибо за ответ. У меня есть еще одна таблица данных со следующим запросом: {SELECT AID, Level1, Level2, Level3, Name FROM table1;} и я хочу иметь на ее основе трехуровневое древовидное представление. Какие изменения мне следует внести в приведенные выше коды? Столбцы Level1, Level2 и Level3 представляют собой коды. Таблица 1

user24059174 12.05.2024 10:36

@Seyyed2 Seyyed2, комментарий к принятому ответу - не место для того, чтобы задавать новый вопрос. Если у вас есть новый вопрос, опубликуйте новый вопрос со всей информацией, относящейся к этому вопросу, включая то, что вы уже пробовали сами. Если вы считаете, что предоставление ссылки на этот вопрос повышает ценность, сделайте это.

jmcilhinney 12.05.2024 11:14

Другие вопросы по теме