2010-08-04 97 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

相關問題