Bezdepbonusu7Программирование: статьи и ответы

Вопрос

DataAdapter: можно ли заполнить Collection-Type вместо DataTable / DataSet?

Автор вопроса: Tim SchmelterОтветов: 1

это скорее теоретический вопрос, который я себе задавал. Я вспомнил, что BinarySearch упорядоченного списка (Коллекция в целом ) быстрее, чем поиск строк с помощью Datatable.Rows.Find или DataTable.FindByPK со значением первичного ключа.

Следовательно, я заполняю Datatable из базы данных в общем конструкторе и сразу после этого List (of Int32), который содержит все первичные ключи из этой таблицы. Позже я проверю с помощью BinarySearch, содержит ли список значения первичного ключа. Но поскольку datatable в любом случае содержит только PK-Column, я спросил себя, есть ли способ избежать огромных накладных расходов на заполнение Datatable и после этого добавления всех строк в список. Можно ли заполнить общий список (или другой тип коллекции) вместо Datatable / Dataset непосредственно из Dataadapter? Может быть, я сбился с пути, и есть другой способ избежать лишнего зацикливания, которого мне не хватает.

Код заполнения DataTable в строго типизированном наборе данных и списке:

   Private Shared w205CorrectSWUpgrades As New List(Of Int32)

   Shared Sub New()
        Dim da As New dsDatabaseTableAdapters.W205SWUpgradesTableAdapter
        For Each row As dsDatabase.W205SWUpgradesRow In da.Get_W205CorrectSWUpgrades.Rows
           w205CorrectSWUpgrades.Add(row.idData)
        Next
    End Sub

ОБНОВЛЕНИЕ. Для полноты картины мое решение (спасибо TheCloudlessSky): поскольку DataAdapter сам использует DataReader для заполнения Datatable или Dataset, лучшим способом было расширить сгенерированный (из VS) частичный класс DataAdapter с новой функцией, которая возвращает список (из Int32), заполненный непосредственно из базы данных. Помните, что этот частичный класс должен находиться в другом файле, чем сгенерированный класс, иначе ваш исходный код будет перезаписан при изменениях в наборе данных. Также помните, что он должен находиться в том же пространстве имен (оканчивается адаптерами таблиц) и, конечно же, иметь то же имя.

 Namespace dsDatabaseTableAdapters
    Partial Public Class W205SWUpgradesTableAdapter

        Public Function GetListOfW205CorrectSWUpgrades() As System.Collections.Generic.List(Of System.Int32)
            Dim list As New System.Collections.Generic.List(Of System.Int32)
            Dim command As System.Data.SqlClient.SqlCommand = Me.CommandCollection(0)

            Dim previousConnectionState As System.Data.ConnectionState = command.Connection.State
            Try
               If ((command.Connection.State And Global.System.Data.ConnectionState.Open) _
                        <> Global.System.Data.ConnectionState.Open) Then
                   command.Connection.Open()
               End If
               Using reader As System.Data.SqlClient.SqlDataReader = command.ExecuteReader
                   While reader.Read
                      list.Add(reader.GetInt32(0))
                   End While
               End Using
            Finally
                If (previousConnectionState = System.Data.ConnectionState.Closed) Then
                    command.Connection.Close()
                End If
            End Try

            Return list
        End Function

    End Class
End Namespace

Теперь бизнес-логика и уровень доступа к данным по-прежнему строго разделены (в отдельных проектах):

    Private Shared w205CorrectSWUpgrades As List(Of Int32)

    Shared Sub New()
        Dim da As New dsDatabaseTableAdapters.W205SWUpgradesTableAdapter
        w205CorrectSWUpgrades = da.GetListOfW205CorrectSWUpgrades
    End Sub

collectionsperformance

Ответы

Ответ 1 · рейтинг 4 · TheCloudlessSky

Почему бы вам не использовать вместо этого DataReader, поскольку это довольно тривиально? В C # вы бы сделали следующее:

List<int> primaryKeys = new List<int>();

using (SqlConnection conn = new SqlConnection("your connection string"))
{
    SqlCommand command = new SqlCommand("SELECT Id FROM Table", conn);

    using (SqlDataReader reader = command.ExecuteReader())
    {
        // Loop through each record.
        while (reader.Read())
        {
            primaryKeys.Add(reader.GetInt32(0));
        }
    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы