2010-08-04 86 views
2

这是我自问的一个理论问题。 I remembered有序列表(一般收集)的BinarySearch比找到具有主键值的Datatable.Rows.Find or DataTable.FindByPK的行更快。DataAdapter:是否可以填充集合类型而不是DataTable/DataSet?

因此,我从共享构造函数中的数据库中填充一个Datatable,并在那之后立即包含该表中所有主键的List(Int32)。稍后我会检查BinarySearch列表是否包含主键值。但是因为datatable无论如何只包含PK-Column,所以我问自己是否有办法避免填充Datatable的巨大开销,以及在将所有行添加到列表之后。 是否可以直接从DataAdapter填充通用List(或其他集合类型)而不是Datatable/Dataset? 也许我不在赛道上,还有另一种方法可以避免我缺少的Extra-Loop。

填写一个强类型数据集的数据表和列表的代码:

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 

UPDATE: 为了完整我的解决方案(感谢TheCloudlessSky)的缘故: 因为DataAdapter的本身使用DataReader来填充数据表或数据集,最好的方法是使用一个新的函数来扩展(从VS)生成的DataAdapter的部分类,该函数返回直接从数据库填充的List(Int32)。请记住,此分部类必须位于生成的类以外的其他文件中,否则,您的源代码将在数据集中的更改上被覆盖。还要记住它必须位于同一个命名空间中(以TableAdapter结尾),当然也有相同的名称。

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 

回答

4

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

这是我第一次想到的,并且会是一个答案。但是DataReader的一大缺点是,在遍历行时需要实时连接数据库。这将是一个瓶颈,因为我的问题针对的是大量数据。但+1,多谢了 – 2010-08-04 12:16:22

+0

另一方面,我认为这是Ado.Net的唯一答案,不是吗?另一个缺点是我无法将我的强类型数据集与Datareader一起使用。 – 2010-08-04 12:25:39

+1

@Tim - 当迭代结果时,你当然需要活连接。 DataReader是DataAdapter用来获取数据的。 ADO.NET *是一个用于.NET数据访问的术语,“DataReader”是其中的一部分。这是所有其他“数据访问”类用来从SQL等数据源读取的内容。你不需要一个强类型的数据集,因为它只是被返回的int。 – TheCloudlessSky 2010-08-04 13:32:15

相关问题