共用方式為


從 DataAdapter 填入 DataSet

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

DataAdapterSelectCommand 屬性為 Command 物件,可用來從資料來源擷取資料。DataAdapterInsertCommandUpdateCommandDeleteCommand 屬性為 Command 物件,可根據對 DataSet 內資料的修改,管理對資料來源內資料的更新作業。這些屬性的更詳細內容皆涵蓋在以 DataAdapter 更新資料來源中。

DataAdapterFill 方法是用來把 DataAdapterSelectCommand 結果填入 DataSetFill 把下列各項當成引數:要填入的 DataSetDataTable 物件,或是以 SelectCommand 傳回資料列填入的 DataTable 名稱。

Fill 方法使用 DataReader 物件隱含傳回資料行名稱、用來在 DataSet 內建立資料表的型別,以及用來填入 DataSet 內資料表資料列的資料。資料表和資料行只有在不存在時才會被建立;不然 Fill 便會使用現有的 DataSet 結構描述。資料行型別會根據將 .NET 資料提供者資料型別對應至 .NET Framework 資料型別 內的資料表建立為 .NET Framework 型別。除非主索引鍵存在資料來源中,並且將 DataAdapter.MissingSchemaAction 設為 MissingSchemaAction.AddWithKey,否則不會建立主索引鍵。如果 Fill 發現主索引鍵已在資料表中,它就會以資料列 (其主索引鍵的資料行值,符合從資料來源傳回的資料列對應值) 的資料來源資料,覆寫 DataSet 中的資料。如果沒發現主索引鍵,則資料會附加在 DataSet 的資料表內。Fill DataSet 時,使用任何可能存在的對應 (請參閱設定 DataTable 和 DataColumn 對應)。

Note注意事項

如果 SelectCommand 傳回 OUTER JOIN 的結果,則 DataAdapter 便不會為產生的 DataTable 設定 PrimaryKey 值。您將需要自己定義 PrimaryKey,以確保重複資料列正確解析。如需詳細資訊,請參閱定義資料表的主索引鍵

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

範例

' Assumes that connection is a valid SqlConnection object.
Dim queryString As String = _
  "SELECT CustomerID, CompanyName FROM dbo.Customers"
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
  queryString, connection)

Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")
// 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");
Note注意事項

這個範例所顯示的程式碼並未明確開啟和關閉 ConnectionFill 方法若發現連接尚未開啟,會隱含開啟 DataAdapter 正在使用的 Connection。如果 Fill 開啟了連接,則當 Fill 結束時也會一併關閉連接。如此便可在處理單一作業,例如 FillUpdate時,簡化您的程式碼。但是,如果您要執行需要開啟連接的多項作業,您可明確呼叫 ConnectionOpen 方法,針對資料來源執行作業,然後呼叫 ConnectionClose 方法,如此即可改善應用程式的效能。您應該儘量減少與資料來源之間的連接,以釋放資源給其他用戶端應用程式使用。

多個結果集

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

從多重 DataAdapters 填入 DataSet

不論 DataAdapter 的數量多寡,都可以搭配 DataSet 使用。每個 DataAdapter 可用來填入一個或多個 DataTable 物件,並將更新解析回相關資料來源。DataRelationConstraint 物件可從本機加入 DataSet,讓您在來自不同資料來源的資料間建立關聯。例如,DataSet 包含的資料可來自 Microsoft SQL Server 資料庫、透過 OLE DB 公開的 IBM DB2 資料庫和產生 XML 資料流的資料來源。一個或數個 DataAdapter 物件就能處理與每個資料來源的通訊。

範例

下列程式碼範例從 Microsoft SQL Server 2000 上的 Northwind 資料庫填入客戶清單,並從存放在 Microsoft Access 2000 的 Northwind 資料庫填入訂貨清單。填入的資料表和 DataRelation 有關,之後客戶清單便會顯示該客戶的訂貨。如需關於 DataRelation 物件的詳細資訊,請參閱在資料表間加入關聯性巡覽資料表之間的關聯性

' Assumes that customerConnection is a valid SqlConnection object.
' Assumes that orderConnection is a valid OleDbConnection object.
Dim custAdapter As SqlDataAdapter = New SqlDataAdapter( _
  "SELECT * FROM dbo.Customers", customerConnection)

Dim ordAdapter As OleDbDataAdapter = New OleDbDataAdapter( _
  "SELECT * FROM Orders", orderConnection)

Dim customerOrders As DataSet = New DataSet()
custAdapter.Fill(customerOrders, "Customers")
ordAdapter.Fill(customerOrders, "Orders")

Dim relation As DataRelation = _
  customerOrders.Relations.Add("CustOrders", _
  customerOrders.Tables("Customers").Columns("CustomerID"), _ 
  customerOrders.Tables("Orders").Columns("CustomerID"))

Dim pRow, cRow As DataRow
For Each pRow In customerOrders.Tables("Customers").Rows
  Console.WriteLine(pRow("CustomerID").ToString())

  For Each cRow In pRow.GetChildRows(relation)
    Console.WriteLine(vbTab & cRow("OrderID").ToString())
  Next
Next 
// Assumes that customerConnection is a valid SqlConnection object.
// Assumes that orderConnection is a valid OleDbConnection object.
SqlDataAdapter custAdapter = new SqlDataAdapter(
  "SELECT * FROM dbo.Customers", customerConnection);
OleDbDataAdapter ordAdapter = new OleDbDataAdapter(
  "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 Decimal 型別

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

ADO.NET 2.0 已在 DataSet 中加強對 System.Data.SqlTypes 的支援。如需詳細資訊,請參閱SqlType 和 DataSet

OLE DB 章節

您可以使用階層式資料列集 (Rowset),或稱章節 (OLE DB 型別 DBTYPE_HCHAPTER、ADO 型別 adChapter) 來填入 DataSet 的內容。若在 Fill 作業期間,OleDbDataAdapter 遇到已章節化的資料行,則會針對該章節化的資料行建立 DataTable,且該資料表會填入來自章節的資料行和資料列。為章節化資料行所建立的資料表會以 "ParentTableNameChapteredColumnName" 的形式,取用父資料表名稱和章節化資料行名稱來命名。如果 DataSet 中已有資料表,且與章節化資料行的名稱相符,則目前的資料表內會填入章節資料;如果現有資料表內沒有資料行符合章節內的資料行,則會加入新資料行。

DataSet 內的資料表中填入章節化資料行的資料前,會在階層式資料列集的父子資料表間建立關聯,方法是在父子資料表兩方均加入整數資料行,將父資料行設為自動遞增,然後使用新增自兩個資料表的資料行來建立 DataRelation。加入的關聯以 "ParentTableNameChapterColumnName" 形式,使用父資料表和章節化資料行的名稱來命名。

請注意,關聯資料行僅存在於 DataSet。從資料來源後續填入會造成在資料表內加入新資料列,而非將變更合併至現有資料列。

也要注意的是,如果您使用的 DataAdapter.Fill 多載採用 DataTable,則只有該資料表會被填入。自動遞增的整數資料行仍會被加入資料表,但不會建立或填入子資料表,也不會建立關聯。

下列範例使用 MSDataShape 提供者產生客戶清單中每位客戶訂單的章節資料行。接著便在 DataSet 內填入資料。

Using connection As OleDbConnection = New OleDbConnection( _
  "Provider=MSDataShape;Data Provider=SQLOLEDB;" & _
  "Data Source=(local);Integrated " & _
  "Security=SSPI;Initial Catalog=northwind")

Dim adapter As OleDbDataAdapter = New OleDbDataAdapter( _
  "SHAPE {SELECT CustomerID, CompanyName FROM Customers} " & _
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " & _
  "RELATE CustomerID TO CustomerID)", connection)

Dim customers As DataSet = New DataSet()

adapter.Fill(customers, "Customers")
End Using
using (OleDbConnection connection = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
  "Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind"))
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +
  "RELATE CustomerID TO CustomerID)", connection);

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

Fill 作業完畢後,DataSet 會包含兩個資料表:CustomersCustomersOrders,其中 CustomersOrders 表示章節化的資料行。接下來,將另一個名為 Orders 的資料行加入 Customers 資料表,另一個名為 CustomersOrders 的資料行則會加入 CustomersOrders 資料表。Customers 資料表內的 Orders 資料行設為自動遞增。接著使用加入資料表的資料行 (將 Customers 當做父資料表),建立 DataRelationCustomersOrders。下表顯示一些範例結果。

TableName:Customers

CustomerID CompanyName Orders

ALFKI

Alfreds Futterkiste

0

ANATR

Ana Trujillo Emparedados y helados

1

TableName:CustomersOrders

CustomerID OrderID CustomersOrders

ALFKI

10643

0

ALFKI

10692

0

ANATR

10308

1

ANATR

10625

1

請參閱

概念

將資料提供者資料型別對應至 .NET Framework 資料型別

其他資源

使用 DataAdapters
使用多重作用結果集
使用 SqlType