DataSet 的 Merge 方法
是MSDN中對(duì)Merge方法使用說(shuō)明:
Merge 方法用于合并架構(gòu)大致相似的兩個(gè) DataSet 對(duì)象。合并在客戶端應(yīng)用程序上通常用于將數(shù)據(jù)源中最近的更改合并到現(xiàn)有的 DataSet 中。這使客戶端應(yīng)用程序能夠擁有用數(shù)據(jù)源中的最新數(shù)據(jù)刷新的 DataSet。通常在一系列過(guò)程的末尾調(diào)用 Merge 方法,這些過(guò)程涉及驗(yàn)證更改、消除錯(cuò)誤、使用更改更新數(shù)據(jù)源并最后刷新現(xiàn)有的 DataSet。 在客戶端應(yīng)用程序中,通常有這樣一個(gè)按鈕,用戶可以單擊它來(lái)收集已更改的數(shù)據(jù)并對(duì)其進(jìn)行驗(yàn)證,然后將其發(fā)送回中間層組件。在這種情況下,將首先調(diào)用 GetChanges 方法。該方法返回另一個(gè)為驗(yàn)證和合并而優(yōu)化的 DataSet。第二個(gè) DataSet 對(duì)象只包含已更改的 DataTable 和 DataRow 對(duì)象,結(jié)果產(chǎn)生初始 DataSet 的子集。該子集通常較小,因此可以更有效率地傳遞回中間層組件。然后,中間層組件將通過(guò)存儲(chǔ)過(guò)程使用更改更新初始數(shù)據(jù)源。然后,中間層可以發(fā)送回一個(gè)新的 DataSet,其中包含數(shù)據(jù)源中的初始數(shù)據(jù)和最新數(shù)據(jù)(通過(guò)再次運(yùn)行初始查詢);或者它可以發(fā)送回包含從數(shù)據(jù)源對(duì)其進(jìn)行的所有更改的子集。(例如,如果數(shù)據(jù)源自動(dòng)創(chuàng)建唯一主鍵值,則可以將這些值傳播回客戶端應(yīng)用程序。)在哪一種情況下都可以使用 Merge 方法將返回的 DataSet 合并回客戶端應(yīng)用程序的初始 DataSet。 當(dāng)將新的源 DataSet 合并到目標(biāo)中時(shí),DataRowState 值為 Unchanged、Modified 或 Deleted 的任何源行都會(huì)與具有同一主鍵值的目標(biāo)行相匹配。DataRowState 值為 Added 的源行將匹配主鍵值與新源行相同的新目標(biāo)行。
根據(jù)以上說(shuō)明,我們知道Merge方法在合并兩個(gè)數(shù)據(jù)集時(shí),是以行的主鍵值為主要對(duì)比參照。這樣在向數(shù)據(jù)集添加新行時(shí)不會(huì)有任何問(wèn)題,在修改了行且不修改主鍵值的情況下也不會(huì)有問(wèn)題,但是在更改行時(shí)如果你修改了主鍵的值,那問(wèn)題就來(lái)了…… 下面我們就舉例說(shuō)明:
在SQL Server下的一個(gè)Products表結(jié)構(gòu)如下:
在SQL Server下的一個(gè)Products表結(jié)構(gòu)如下:
| 列名 | 數(shù)據(jù)類型 | 說(shuō)明 |
| Code | nchar | 產(chǎn)品代碼(主鍵列) |
| Name | nvarchar | 產(chǎn)名名稱 |
| UnitPrice | numeric | 產(chǎn)品單價(jià) |
在.NET中使用XSD生成一個(gè)對(duì)應(yīng)的ProductsData.xsd結(jié)構(gòu)如下:
| 列名 | 數(shù)據(jù)類型 | 說(shuō)明 |
| Code | string | 產(chǎn)品代碼(主鍵列) |
| Name | string | 產(chǎn)名名稱 |
| UnitPrice | decimal | 產(chǎn)品單價(jià) |
根據(jù)MSDN的說(shuō)明,我們?cè)谇芭_(tái)通過(guò)ProductsData添加或修改數(shù)據(jù)后在提交后臺(tái)更新時(shí),通常做法如下:
??????? // 創(chuàng)建一個(gè)新數(shù)據(jù)集來(lái)保存對(duì)主數(shù)據(jù)集所做的更改
??????? ProductsData dataSetChanges;
??????? dataSetChanges = (ProductsData)(productsData.GetChanges());
??????? // 檢查是否做了任何更改
??????? if(dataSetChanges != null) {
??????????? try {
??????????????? // 需要做一些更改,所以嘗試通過(guò)調(diào)用 update 方法
// 和傳遞數(shù)據(jù)集以及任何參數(shù)來(lái)更新數(shù)據(jù)源
??????????????? UpdateDataSource(dataSetChanges);
??????????????? productsData.Merge(dataSetChanges);
??????????????? productsData.AcceptChanges();
??????????? }
??????????? catch (System.Exception eUpdate) {
??????????????? throw eUpdate;
??????????? }
??????? }
以上代碼是根據(jù)VS.NET的數(shù)據(jù)窗體生成向?qū)?xiě)的,依據(jù)以上代碼我們模擬向數(shù)據(jù)集添加一行數(shù)據(jù)并更新后的情況:
| Code | Name | UnitPrice |
| 1001 | 金砂朱古力 | 120.00 |
沒(méi)問(wèn)題,下面我們修改這行數(shù)據(jù)再更新,這里我們把Code改為1002,更新之后結(jié)果數(shù)據(jù)并沒(méi)有按我們預(yù)想的把原本行Code列的值1001改為1002,而是添加了一行:
| Code | Name | UnitPrice |
| 1001 | 金砂朱古力 | 120.00 |
| 1002 | 金砂朱古力 | 130.00 |
注:通常情況下我們是很少更改主鍵值,但在代碼沒(méi)有被使用的情況下,一般是允許更改Code的,特別是在系統(tǒng)實(shí)施的階段。
出現(xiàn)以上問(wèn)題的原因其實(shí)不奇怪,按Merge方法的原理,這一點(diǎn)也沒(méi)錯(cuò),但這是我們不希望的結(jié)果,怎么解決呢,難道不允許用戶更改主鍵,但好象不符合實(shí)際。怎么解決呢?
既然要用Merge方法,那只有依Merge合并數(shù)據(jù)的原理去做,不讓改主鍵我們就不改主鍵,我們可以給前臺(tái)的ProductsData的數(shù)據(jù)集加多一個(gè)額外的主鍵ID列,并把它的AutoIncrement設(shè)為true,將原本的主鍵列Code改為Key列,至于后臺(tái)SQL Server中的源表不作任何修改,修改后如下:
| 列名 | 數(shù)據(jù)類型 | 說(shuō)明 |
| ID | Int | 自動(dòng)增長(zhǎng)列 (主鍵) |
| Code | String | 產(chǎn)品代碼?? (key 鍵) |
| Name | String | 產(chǎn)名名稱 |
| UnitPrice | decimal | 產(chǎn)品單價(jià) |
經(jīng)這樣一改,由于ID是自動(dòng)一個(gè)自遞增列,我們并不去修改它的值,這樣我們就可以隨意更改 Code 列的值了,Merge 方法在合并數(shù)據(jù)時(shí)由于是依據(jù)ID例進(jìn)行比對(duì)所以也不會(huì)再出現(xiàn)前面加多一行的問(wèn)題了。
總結(jié)
以上是生活随笔為你收集整理的DataSet 的 Merge 方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: iframe 中 js 的 cookie
- 下一篇: jquery获取一个table中的一行的