是MSDN中對Merge方法使用說明:
Merge 方法用于合并架構大緻相似的兩個 DataSet 對象。合并在用戶端應用程式上通常用于将資料源中最近的更改合并到現有的 DataSet 中。這使用戶端應用程式能夠擁有用資料源中的最新資料重新整理的 DataSet。通常在一系列過程的末尾調用 Merge 方法,這些過程涉及驗證更改、消除錯誤、使用更改更新資料源并最後重新整理現有的 DataSet。 在用戶端應用程式中,通常有這樣一個按鈕,使用者可以單擊它來收集已更改的資料并對其進行驗證,然後将其發送回中間層元件。在這種情況下,将首先調用 GetChanges 方法。該方法傳回另一個為驗證和合并而優化的 DataSet。第二個 DataSet 對象隻包含已更改的 DataTable 和 DataRow 對象,結果産生初始 DataSet 的子集。該子集通常較小,是以可以更有效率地傳遞回中間層元件。然後,中間層元件将通過存儲過程使用更改更新初始資料源。然後,中間層可以發送回一個新的 DataSet,其中包含資料源中的初始資料和最新資料(通過再次運作初始查詢);或者它可以發送回包含從資料源對其進行的所有更改的子集。(例如,如果資料源自動建立唯一主鍵值,則可以将這些值傳播回用戶端應用程式。)在哪一種情況下都可以使用 Merge 方法将傳回的 DataSet 合并回用戶端應用程式的初始 DataSet。 當将新的源 DataSet 合并到目标中時,DataRowState 值為 Unchanged、Modified 或 Deleted 的任何源行都會與具有同一主鍵值的目标行相比對。DataRowState 值為 Added 的源行将比對主鍵值與新源行相同的新目标行。
根據以上說明,我們知道Merge方法在合并兩個資料集時,是以行的主鍵值為主要對比參照。這樣在向資料集添加新行時不會有任何問題,在修改了行且不修改主鍵值的情況下也不會有問題,但是在更改行時如果你修改了主鍵的值,那問題就來了…… 下面我們就舉例說明:
在SQL Server下的一個Products表結構如下:
列名
資料類型
說明
Code
nchar
産品代碼(主鍵列)
Name
nvarchar
産名名稱
UnitPrice
numeric
産品單價
在.NET中使用XSD生成一個對應的ProductsData.xsd結構如下:
string
decimal
根據MSDN的說明,我們在前台通過ProductsData添加或修改資料後在送出背景更新時,通常做法如下:
// 建立一個新資料集來儲存對主資料集所做的更改
ProductsData dataSetChanges;
dataSetChanges = (ProductsData)(productsData.GetChanges());
// 檢查是否做了任何更改
if(dataSetChanges != null) {
try {
// 需要做一些更改,是以嘗試通過調用 update 方法
// 和傳遞資料集以及任何參數來更新資料源
UpdateDataSource(dataSetChanges);
productsData.Merge(dataSetChanges);
productsData.AcceptChanges();
}
catch (System.Exception eUpdate) {
throw eUpdate;
}
以上代碼是根據VS.NET的資料窗體生成向導寫的,依據以上代碼我們模拟向資料集添加一行資料并更新後的情況:
1001
金砂朱古力
120.00
沒問題,下面我們修改這行資料再更新,這裡我們把Code改為1002,更新之後結果資料并沒有按我們預想的把原本行Code列的值1001改為1002,而是添加了一行:
1002
130.00
注:通常情況下我們是很少更改主鍵值,但在代碼沒有被使用的情況下,一般是允許更改Code的,特别是在系統實施的階段。
出現以上問題的原因其實不奇怪,按Merge方法的原理,這一點也沒錯,但這是我們不希望的結果,怎麼解決呢,難道不允許使用者更改主鍵,但好象不符合實際。怎麼解決呢?
既然要用Merge方法,那隻有依Merge合并資料的原理去做,不讓改主鍵我們就不改主鍵,我們可以給前台的ProductsData的資料集加多一個額外的主鍵ID列,并把它的AutoIncrement設為true,将原本的主鍵列Code改為Key列,至于背景SQL Server中的源表不作任何修改,修改後如下:
ID
Int
自動增長列 (主鍵)
String
産品代碼 (key 鍵)
經這樣一改,由于ID是自動一個自遞增列,我們并不去修改它的值,這樣我們就可以随意更改 Code 列的值了,Merge 方法在合并資料時由于是依據ID例進行比對是以也不會再出現前面加多一行的問題了。
本文轉自左正部落格園部落格,原文連結:http://www.cnblogs.com/soundcode/archive/2013/01/16/2862273.html,如需轉載請自行聯系原作者