利用適配器解決ADO.NET批處理
ADO.NET經過長時間的發展,很多用戶都很了解ADO.NET批處理了,這里我發表一下個人理解,和大家討論討論。 在進一步詳細討論 ADO.NET 批處理更新之前,我需要闡明常常會導致某種誤解的批處理更新模型的一個方面。雖然更新和批處理更新在 ADO.NET 內的實際實現方面有著本質的區別,但它們遵循的是同一個更新模型。更新和批處理更新都是通過直接的并且特定于提供程序的語句來完成的。當然,由于批處理更新通常涉及到更多的行,所以這些語句會被組合為一個批處理調用。
ADO.NET批處理更新會對目標數據集的行進行從頭到尾的循環,只要發現更新的行,就會發出適當的更新命令(INSERT、DELETE 或 UPDATE)。對更新的行進行通信時,將運行一個預定義的直接 SQL 命令。從本質上來說,這就是批處理更新。
這個過程是理所當然的。實際上,如果批處理更新使用完全不同的更新模型,就需要來自數據源的特殊支持。(這正是向 SQL Server 2000 提交 XML updategram 時發生的情況。)批處理更新只是一個用來簡化多個行更新提交的客戶端提供的軟件機制。在任何情況下,每個新行提交總是通過數據源直接命令的正常通道完成的。
#T#到目前為止,本文只提及了 SQL 命令,但這些提及的內容都明確表明了 ADO 批處理更新實現和 ADO.NET 批處理更新實現之間的一個重要區別。在 ADO 中,批處理更新只可能發生在基于 SQL 的數據源上。而在 ADO.NET 中,批處理更新則可能發生在任何種類的托管提供程序上,其中包括那些不應該通過 SQL 查詢語言公開其數據的托管提供程序。現在,我們可以開始討論 ADO.NET 批處理更新編程的關鍵內容了。
ADO.NET 批處理更新通過數據適配器對象的 “更新” 方法進行。數據只能以每個表為基礎進行提交。如果您調用 “更新” 時沒有指定表名,則使用 Table 這個默認的表名。如果不存在具有該名稱的表,則會產生異常。“更新” 首先檢查每個表行的 RowState 屬性,然后為所指定表中的每個插入行、更新行或刪除行準備自定義的 INSERT、UPDATE 或 DELETE 語句。 “更新” 方法有幾個超載。它可以采用數據集和數據表提供的對、某個數據表、甚至是一個 DataRow 對象數組。該方法會返回一個整數值,即成功更新的行數。
為了***限度地減少網絡通信,通常會對正在操作的數據集的一個子集調用 “更新”。毫無疑問,這個子集只包含當時已修改的行。您可以通過調用數據集的 GetChanges 方法來獲得這樣的子集。
- if (ds.HasChanges())
- {
- DataSet dsdsChanges = ds.GetChanges();
- adapter.Update(dsChanges, "MyTable");
- }
另外,您可以使用 HasChanges 方法檢查數據集是否發生了更改。HasChanges 返回一個布爾值。 GetChanges 返回的數據集包含當時已插入、刪除或修改的行。但這里所說的當時是什么時間呢?這正是 ADO.NET 批處理更新比較復雜的一個方面,必須與表行的當前狀態一起處理。 行的狀態 “數據表” 中的每一行都是通過 DataRow 對象呈現的。DataRow 對象主要是作為父 “數據表” 對象的 Rows 集合的一個元素而存在的。
從概念上來看,數據庫行固有地鏈接到了某個給定表的結構。就是由于這個原因,ADO.NET 中的 DataRow 類不提供公用構造函數。創建新 DataRow 對象的唯一方式是借助于對 “數據表” 對象的某個實時實例調用名為 NewRow 的方法。剛剛創建好的行還不屬于父表的 Rows 集合,但該行與此集合的關系決定了該行的狀態。下表顯示了 RowState 屬性的一些可取值。這些值組合在了 DataRowState 枚舉中。