【问题标题】:DataAdapter: Is it possible to fill a Collection-Type instead of a DataTable/DataSet?DataAdapter:是否可以填充 Collection-Type 而不是 DataTable/DataSet?
【发布时间】:2011-03-25 05:05:51
【问题描述】:

这更像是我问自己的一个理论问题。 我remembered 认为有序列表(通常是集合)的 BinarySearch 比查找具有主键值的 Datatable.Rows.Find or DataTable.FindByPK 的行要快。

因此,我在共享构造函数中填充数据库中的数据表,然后立即填充包含该表中所有主键的 List(of Int32)。稍后我将使用 BinarySearch 检查列表是否包含主键值。但是因为无论如何数据表只包含 PK 列,我问自己是否有办法避免填充数据表的巨大开销,然后将所有行添加到列表中。 是否可以直接从数据适配器填充通用列表(或其他集合类型)而不是数据表/数据集? 也许我偏离了轨道,还有另一种方法可以避免我错过的 Extra-Loop。

强类型Dataset和List中填充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 的部分类,该函数返回直接从数据库填充的 List(of Int32)。请记住,此部分类必须位于生成的类之外的其他文件中,否则您的源代码将被数据集中的更改覆盖。还要记住,它必须在同一个命名空间中(以 TableAdapters 结尾),并且当然具有相同的名称。

 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

【问题讨论】:

    标签: .net vb.net performance ado.net collections


    【解决方案1】:

    为什么不使用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));
            }
        }
    }   
    

    【讨论】:

    • 这是我首先想到的,也是一个答案。但 DataReader 的一大缺点是在遍历行时需要与数据库建立实时连接。这将是一个瓶颈,因为我的问题针对大量数据。但是 +1,无论如何谢谢
    • 另一方面,我认为这是 Ado.Net 中唯一的答案,不是吗?另一个缺点是我无法将我的强类型数据集与 Datareader 一起使用。
    • @Tim - 当然,在遍历结果时需要活动连接。 DataReaderDataAdapter 用来获取 它的 数据的。 ADO.NET 使用 .NET 进行数据访问的术语,DataReader 是其中的一部分。它是所有其他“数据访问”类用来从 SQL 等数据源读取的内容。您不需要强类型数据集,因为返回的只是 int
    • @TheCloudlessSky:我认为 DataAdapter 会以不同于使用 Datareader 的方式填充数据表/数据集,但以下文章强调了您的声明:msdn.microsoft.com/en-us/magazine/cc188717.aspx
    • 好的,我把你的数据阅读器作为答案。但不幸的是,我将业务逻辑与数据访问层混合在一起。
    猜你喜欢
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 2012-02-05
    • 2013-01-15
    • 2021-11-25
    • 1970-01-01
    相关资源
    最近更新 更多