在 .NET Framework 應用程式中使用 TableAdapters 填滿資料集
注意
資料集和相關類別是 2000 年代初的舊版 .NET Framework 技術,可讓應用程式在應用程式與資料庫中斷連線時使用記憶體中的資料。 這些技術特別適用於可讓使用者修改資料並將變更保存回資料庫的應用程式。 雖然已證明資料集是非常成功的技術,但建議新的 .NET 應用程式使用 Entity Framework Core。 Entity Framework 提供更自然的方式,將表格式資料作為物件模型使用,而且具有更簡單的程式設計介面。
TableAdapter 元件會根據您指定的一或多個查詢或預存程序,以資料庫中的資料填入資料集。 TableAdapter 也可對資料庫執行新增、更新和刪除,以保存您對資料集所做的變更。 您也可以發出與任何特定資料表無關的全域命令。
注意
TableAdapter 由 Visual Studio 設計工具所產生。 如果您要以程式設計方式建立資料集,請使用 DataAdapter (這是一種 .NET 類別)。
如需 TableAdapter 作業的詳細資訊,您可以直接跳到下列其中一個主題:
主題 | 說明 |
---|---|
建立和設定 TableAdapter | 如何使用設計工具建立及設定 TableAdapter |
建立參數型 TableAdapter 查詢 | 如何讓使用者為 TableAdapter 程序或查詢提供引數 |
以 TableAdapter 直接存取資料庫 | 如何使用 TableAdapter 的 Dbdirect 方法 |
填入資料集時關閉條件約束 | 如何在更新資料時使用外部索引鍵條件約束 |
如何擴充 TableAdapter 的功能 | 如何將自訂程式碼新增至 TableAdapter |
將 XML 資料讀入資料集 | 如何使用 XML |
TableAdapter 概觀
TableAdapter 是設計工具產生的元件,可連線至資料庫、執行查詢或預存程序,並以傳回的資料填入其 DataTable。 TableAdapter 也會將更新的資料從您的應用程式傳回至資料庫。 您可以視需要對 TableAdapter 執行任意數量的查詢,只要查詢傳回的資料符合與 TableAdapter 相關聯之資料表的結構描述即可。 下圖顯示 TableAdapter 如何與資料庫和記憶體中的其他物件互動:
雖然 TableAdapter 是使用 資料集設計工具設計的,但產生的 TableAdapter 類別並不是 DataSet 的巢狀類別。 它們位於各個資料集專屬的個別命名空間中。 例如,如果您具有名為 NorthwindDataSet
的資料集,則與 NorthwindDataSet
中的 DataTable 相關聯的 TableAdapter 會位於 NorthwindDataSetTableAdapters
命名空間中。 若要以程式設計方式存取特定的 TableAdapter,您必須宣告新的 TableAdapter 執行個體。 例如:
NorthwindDataSet northwindDataSet = new NorthwindDataSet();
NorthwindDataSetTableAdapters.CustomersTableAdapter customersTableAdapter =
new NorthwindDataSetTableAdapters.CustomersTableAdapter();
customersTableAdapter.Fill(northwindDataSet.Customers);
相關聯的 DataTable 結構描述
建立 TableAdapter 時,您會使用初始查詢或預存程序為 TableAdapter 相關聯的 DataTable 定義結構描述。 您可藉由呼叫 TableAdapter 的 Fill
方法 (會填入 TableAdapter 相關聯的 DataTable) 來執行此初始查詢或預存程序。 對 TableAdapter 的主要查詢所做的任何變更,都會反映在相關資料表的結構描述中。 例如,從主要查詢中移除資料行,也會從相關聯的資料表中移除資料行。 如果對 TableAdapter 執行的任何其他查詢所使用的 SQL 陳述式傳回了不在主要查詢中的資料行,則設計工具會嘗試同步處理主要查詢與其他查詢之間的資料行變更。
TableAdapter 更新命令
TableAdapter 的更新功能取決於 TableAdapter 精靈的主要查詢中有多少可用資訊。 例如,設定為從多個資料表 (使用 JOIN
)、純量值、檢視或彙總函式的結果擷取值的 TableAdapter,在建立之初並不具備將更新傳回至基礎資料庫的能力。 但您可在 [屬性] 視窗中手動設定 INSERT
、UPDATE
和 DELETE
命令。
TableAdapter 查詢
TableAdapter 可包含多個查詢,用以填入其相關聯的資料表。 您可以視應用程式的需要為 TableAdapter 定義相當數量的查詢,只要每個查詢傳回的資料符合其相關資料表的結構描述即可。 此功能可讓 TableAdapter 根據不同的準則載入不同的結果。
例如,如果您的應用程式包含具有客戶名稱的資料表,您可以建立一個查詢,並在資料表中填入每個以特定字母開頭的客戶名稱,同時建立另建立一個查詢,並在資料表中填入所有位於同一州的客戶。 若要在 Customers
資料表中填入位於指定州的客戶,您可以建立用參數表示州值的 FillByState
查詢,如下所示:SELECT * FROM Customers WHERE State = @State
。 您可以呼叫 FillByState
方法並傳入參數值以執行查詢,如下所示:CustomerTableAdapter.FillByState("WA")
。
除了新增查詢以傳回與 TableAdapter 的資料表具有相同結構描述的資料以外,您還可以新增傳回純量(單一) 值的查詢。 例如,即使傳回的資料不符合資料表的結構描述,傳回客戶計數的查詢 (SELECT Count(*) From Customers
) 對 CustomersTableAdapter,
而言仍是有效的。
ClearBeforeFill 屬性
根據預設,每當您執行查詢以填入 TableAdapter 的資料表時,都會清除現有的資料,且只會將查詢的結果載入資料表中。 如果您想要將查詢傳回的資料新增或合併至資料表中的現有資料,請將 TableAdapter 的 ClearBeforeFill
屬性設定為 false
。 無論您是否清除資料,如果您想要保存更新,就必須明確地將其傳回資料庫。 因此,在執行另一個填入資料表的查詢之前,記得要先儲存資料表中所含資料的任何變更。 如需詳細資訊,請參閱使用 TableAdapter 更新資料。
TableAdapter 繼承
TableAdapter 藉由封裝已設定的 DataAdapter 類別來擴充標準資料配接器的功能。 根據預設,TableAdapter 繼承自 Component 類別,且無法轉換成 DataAdapter 類別。 將 TableAdapter 轉換成 DataAdapter 類別會導致 InvalidCastException 錯誤。 若要變更 TableAdapter 的基底類別,您可以使用 資料集設計工具,在 TableAdapter 的 [基底類別] 屬性中指定衍生自 Component 的類別。
TableAdapter 方法和屬性
TableAdapter 類別不是 .NET 類型。 這表示您無法在文件或物件瀏覽器中加以查閱。 它是在設計階段使用先前所述的其中一個精靈建立的。 您在建立 TableAdapter 時為其指派的名稱,會以您使用的資料表名稱為基礎。 例如,當您根據資料庫中名為 Orders
的資料表建立 TableAdapter 時,TableAdapter 就會命名為 OrdersTableAdapter
。 TableAdapter 的類別名稱可使用 資料集設計工具中的 [名稱] 屬性來變更。
以下是 TableAdapter 的常用方法和屬性:
member | 描述 |
---|---|
TableAdapter.Fill |
以 TableAdapter SELECT 命令的結果填入 TableAdapter 相關聯的資料表。 |
TableAdapter.Update |
將變更傳回資料庫,並傳回一個整數,代表受更新影響的資料列數目。 如需詳細資訊,請參閱使用 TableAdapter 更新資料。 |
TableAdapter.GetData |
傳回填入資料的新 DataTable。 |
TableAdapter.Insert |
在資料表中建立新的資料列。 如需詳細資訊,請參閱在資料庫中插入新的記錄。 |
TableAdapter.ClearBeforeFill |
決定在呼叫其中一個 Fill 方法之前是否要先清空資料表。 |
TableAdapter 更新方法
TableAdapter 會使用資料命令來讀取和寫入資料庫。 使用 TableAdapter 的初始 Fill
(主要) 查詢作為基礎來建立相關資料表的結構描述,以及與 TableAdapter.Update
方法相關聯的 InsertCommand
、UpdateCommand
和 DeleteCommand
命令。 呼叫 TableAdapter 的 Update
方法,會執行原本設定 TableAdapter 時所建立的陳述式,而不是您使用 TableAdapter 查詢設定精靈新增的其他查詢之一。
使用 TableAdapter 時,會透過您常執行的命令有效執行相同的作業。 例如,當您呼叫配接器的 Fill
方法時,配接器會在其 SelectCommand
屬性中執行資料命令,並使用資料讀取器 (例如 SqlDataReader) 將結果集載入資料表中。 同樣地,當您呼叫配接器的 Update
方法時,將會針對資料表中每個已變更的記錄執行適當的命令 (在 UpdateCommand
、InsertCommand
和 DeleteCommand
屬性中)。
注意
如果主要查詢中有足夠的資訊,則在產生 TableAdapter 時,依預設會建立 InsertCommand
、UpdateCommand
和 DeleteCommand
命令。 如果 TableAdapter 的主要查詢不只是單一資料表 SELECT
陳述式,則設計工具可能無法產生 InsertCommand
、UpdateCommand
和 DeleteCommand
。 若未產生這些命令,您可能會在執行 TableAdapter.Update
方法時收到錯誤。
TableAdapter GenerateDbDirectMethods
除了 InsertCommand
、UpdateCommand
和 DeleteCommand
以外,TableAdapter 也會使用可直接對資料庫執行的方法來建立。 您可以直接呼叫這些方法 (TableAdapter.Insert
、TableAdapter.Update
和 TableAdapter.Delete
),以在資料庫中操作資料。 這表示您可以從程式碼呼叫這些個別方法,而不是呼叫 TableAdapter.Update
來處理相關聯的資料表擱置的插入、更新和刪除。
如果您不想建立這些直接方法,請將 TableAdapter 的 GenerateDbDirectMethods 屬性設定為 false
(在 [屬性] 視窗中)。 新增至 TableAdapter 的其他查詢是獨立查詢,不會產生這些方法。
TableAdapter 支援可為 Null 的類型
TableAdapter 支援可為 Null 的類型 Nullable(Of T)
和 T?
。 如需 Visual Basic 可為 Null 型別的詳細資訊,請參閱可為 Null 的實值類型。 若要進一步了解 C# 中可為 Null 的類型,請參閱使用可為 Null 的類型。
TableAdapterManager 參考
根據預設,當您建立包含相關資料表的資料集時,會產生 TableAdapterManager 類別。 若要防止產生該類別,請將資料集的 Hierarchical Update
屬性值變更為 false。 當您將具有關聯的資料表拖曳到 Windows Form 或 WPF 頁面的設計介面時,Visual Studio 會宣告類別的成員變數。 若未使用資料繫結,則必須手動宣告變數。
TableAdapterManager 類別不是 .NET 類型。 因此,您無法在文件中加以查閱。 它是在設計階段建立資料集的過程中建立的。
以下是 TableAdapterManager
類別的常用方法和屬性:
member | 描述 |
---|---|
UpdateAll 方法 |
儲存所有資料表中的所有資料。 |
BackUpDataSetBeforeUpdate 屬性 |
決定在執行 TableAdapterManager.UpdateAll method.Boolean 之前是否要先建立資料集的備份複本。 |
tableName TableAdapter 屬性 |
代表 TableAdapter。 產生的 TableAdapterManager 對於其管理的每個 TableAdapter 各包含一個屬性。 例如,具有客戶和訂單資料表的資料集產生時,TableAdapterManager 會包含 CustomersTableAdapter 和 OrdersTableAdapter 屬性。 |
UpdateOrder 屬性 |
控制個別插入、更新和刪除命令的順序。 將其設定為 TableAdapterManager.UpdateOrderOption 列舉中的其中一個值。根據預設, UpdateOrder 會設定為 InsertUpdateDelete。 這表示會對資料集中的所有資料表依序執行插入、更新和刪除。 |
安全性
使用將 CommandType 屬性設定為 Text 的資料命令時,請先仔細檢查從用戶端傳送的資訊,再將其傳至您的資料庫。 惡意使用者可能會嘗試傳送 (插入) 修改過或額外的 SQL 陳述式,以獲得未授權的存取或破壞資料庫。 將使用者輸入傳輸至資料庫之前,請務必確認資訊是否有效。 最佳做法是盡可能使用參數化查詢或預存程序。