使用 DataAdapter 填入 DataSet

適用於: .NET Framework .NET .NET 標準

下載 ADO.NET

ADO.NET DataSet 是記憶體駐留型資料表示法,可提供獨立於資料來源,且具有一致性的關聯式程式設計模型。 DataSet 表示一組完整的資料,包括資料表、條件約束和資料表間的關係。 因為 DataSet 與資料來源無關,所以 DataSet 可包含應用程式的本機資料,以及來自多個資料來源的資料。 與現有資料來源的互動是透過 DataAdapter 控制。

SelectCommand 的 DataAdapter 屬性為 Command 物件,可用於從資料來源擷取資料。 InsertCommand的 UpdateCommand、 DeleteCommand 和 DataAdapter 屬性為 Command 物件,可根據對 DataSet內資料的修改,管理對資料來源內資料的更新作業。 使用 Dataadapter 更新資料來源一文中會更詳細地說明這些屬性。

Fill 的 DataAdapter 方法用於以 DataSet 之 SelectCommand 的結果填入 DataAdapter。 Fill 把下列各項當成引數:要填入的 DataSet 、 DataTable 物件,或是以 DataTable 傳回資料列填入的 SelectCommand名稱。

注意

使用 DataAdapter 擷取所有的資料表要花很多時間,特別是資料表包含許多資料列時。 這是因為存取資料庫,尋找和處理資料,然後再將資料傳輸至用戶端的過程非常耗時。 將整個資料表提取到用戶端時,也會鎖定伺服器上的所有資料列。 若要提升效能,您可以使用 WHERE 子句大幅減少傳回用戶端的資料列數目。 您也可以藉由在 SELECT 陳述式中明確列出所需的資料行,以減少傳回用戶端的資料數量。 另一個不錯的解決方法就是以批次方式擷取資料列 (例如一次擷取數百個資料列),同時僅在用戶端完成目前的批次作業後,才擷取下一批次。

Fill 方法會隱含地使用 DataReader 物件傳回用於在 DataSet內建立資料表的資料行名稱和型別,以及用於填入 DataSet內資料表資料列的資料。 資料表和資料行只有在不存在時才會建立;否則 Fill 會使用現有的 DataSet 結構描述。 資料行類型是根據 ADO.NET 中資料類型對應的資料表,以 .NET Framework 類型的形式建立。 除非資料來源中已有主索引鍵,且 DataAdapter.MissingSchemaAction 設定為 MissingSchemaAction.AddWithKey,否則不會建立主索引鍵。 如果 Fill 發現某個資料表具有主索引鍵,它會使用資料來源中的資料,覆寫 DataSet 中那些主索引鍵資料行值與從資料來源傳回之資料列相符的資料列。 如果沒發現主索引鍵,則資料會附加在 DataSet的資料表內。 Fill 會在您填入 DataSet 時使用任何現有的對應 (請參閱 DataAdapter、DataTable 及 DataColumn 對應)

注意

如果 SelectCommand 傳回 OUTER JOIN 的結果,則 DataAdapter 便不會為產生的 PrimaryKey 設定 DataTable值。 您必須自行定義PrimaryKey,以確保重複的資料列能夠被正確處理。

下列程式碼範例會建立 SqlDataAdapter 的執行個體,使用 SqlConnection 連接到 Microsoft SQL Server Northwind 資料庫,並在 DataSet 中以客戶清單填入 DataTable。 SQL 陳述式和傳遞給 SqlDataAdapter 建構函式的 SqlConnection 引數,會用來建立 SqlDataAdapter 的 SelectCommand 屬性。

範例

// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

注意

這個範例所顯示的程式碼並未明確開啟和關閉 Connection。 Fill 方法如果發現連線尚未開啟,會自動開啟 DataAdapter 正在使用的 Connection。 如果 Fill 開啟了連接,則當 Fill 結束時也會一併關閉連接。 如此便可在處理單一作業時 (例如 Fill 或 Update),簡化您的程式碼。 但是,如果您要執行需要開啟連接的多項作業,您可明確呼叫 Open 的 Connection方法,針對資料來源執行作業,然後呼叫 Close 的 Connection方法,如此即可改善應用程式的效能。 您應該盡量縮短與資料來源保持連線開啟的時間,以釋放資源供其他用戶端應用程式使用。

多個結果集

如果 DataAdapter 發現多個結果集,它便會在 DataSet內建立多個資料表。 資料表會指定 TableN的遞增預設名稱,從 "Table" 開始 (Table0)。 如果將資料表名稱作為引數傳遞給 Fill 方法,則這些資料表會被指定遞增的預設名稱 TableNameN,從 TableName0 的 "TableName" 開始。

使用多個 DataAdapter 填滿 DataSet

不論 DataAdapter 物件的數量多寡,都可以搭配 DataSet 使用。 每個 DataAdapter 都可以用以填滿一個或多個 DataTable 物件,並將更新解析回相關的資料來源。 DataRelation 與 Constraint 物件可新增至本機 DataSet 中,讓您得以建立來自不同資料來源之資料間的關聯。 例如,DataSet 包含的資料來源可能有 Microsoft SQL Server 資料庫、透過 OLE DB 公開的 IBM Db2 資料庫,以及串流 XML 的資料來源。 與每個資料來源的通訊可以由一個或多個 DataAdapter 物件處理。

範例

下列程式碼範例會從 Microsoft SQL Server 上的 Northwind 資料庫填入客戶清單,並從 Microsoft Access 中的 Northwind 資料庫填入訂單清單。 已填入的資料表與 DataRelation相關,接著會顯示客戶清單以及該客戶的訂單。

// Assumes that customerConnection and orderConnection are valid SqlConnection objects.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", customerConnection);
SqlDataAdapter ordAdapter = new SqlDataAdapter(
"SELECT * FROM Orders", orderConnection);

DataSet customerOrders = new DataSet();

custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");

DataRelation relation = customerOrders.Relations.Add("CustOrders",
customerOrders.Tables["Customers"].Columns["CustomerID"],
customerOrders.Tables["Orders"].Columns["CustomerID"]);

foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
{
    Console.WriteLine(pRow["CustomerID"]);
    foreach (DataRow cRow in pRow.GetChildRows(relation))
        Console.WriteLine("\t" + cRow["OrderID"]);
}

SQL Server 十進位資料類型

根據預設,DataSet 會使用 .NET 資料類型來儲存資料。 對大部分的應用程式而言,這些型別可便於表示資料來源資訊, 但是當資料來源中的資料型別為 SQL Server decimal 或 numeric 資料型別時,這種表示可能會造成問題。 .NET decimal 資料類型最多允許 28 位有效位數,而 SQL Server decimal 資料類型則允許 38 位有效位數。 如果 SqlDataAdapter 在 Fill 作業期間判斷 SQL Server decimal 欄位的精確度超過 28 個字元,則目前的資料列不會新增至 DataTable。 反而會發生 FillError 事件,讓您判斷是否會失去精確度,並做出適當回應。 如需 FillError 事件的詳細資訊,請參閱處理 DataAdapter 事件 (英文)。 若要取得 SQL Server decimal 值,您也可以使用 SqlDataReader 物件並呼叫 GetSqlDecimal 方法。

ADO.NET 也包含對 System.Data.SqlTypes 中 DataSet 的增強支援。 如需詳細資訊,請參閱 SqlTypes and the DataSet。