網(wǎng)站運營seo文章大全提供全面的站長運營經(jīng)驗及seo技術(shù)!dataadapter 的 update 方法可調(diào)用來將 dataset 中的更改解析回數(shù)據(jù)源。與 fill 方法類似,update 方法將 dataset 的實例和可選的 datatable 對象或 datatable 名稱用作參數(shù)。dataset 實例是包含已作出的更改的 dataset,而 datatable 標(biāo)識從其中檢索更改的表。
當(dāng)調(diào)用 update 方法時,dataadapter 將分析已作出的更改并執(zhí)行相應(yīng)的命令(insert、update 或 delete)。當(dāng) dataadapter 遇到對 datarow 的更改時,它將使用 insertcommand、updatecommand 或 deletecommand 來處理該更改。這樣,您就可以通過在設(shè)計時指定命令語法并在可能時通過使用存儲過程來盡量提高 ado.net 應(yīng)用程序的性能。在調(diào)用 update 之前,必須顯式設(shè)置這些命令。如果調(diào)用了 update 但不存在用于特定更新的相應(yīng)命令(例如,不存在用于已刪除行的 deletecommand),則將引發(fā)異常。
command 參數(shù)可用于為 dataset 中每個已修改行的 sql 語句或存儲過程指定輸入和輸出值。有關(guān)更多信息,請參閱將參數(shù)用于 dataadapter。
如果 datatable 映射到單個數(shù)據(jù)庫表或從單個數(shù)據(jù)庫表生成,則可以利用 commandbuilder 對象自動生成 dataadapter 的 deletecommand、insertcommand 和 updatecommand。有關(guān)更多信息,請參閱自動生成的命令。
update 方法會將更改解析回數(shù)據(jù)源,但是自上次填充 dataset 以來,其他客戶端可能已修改了數(shù)據(jù)源中的數(shù)據(jù)。若要使用當(dāng)前數(shù)據(jù)刷新 dataset,請再次使用 dataadapter 填充 (fill) dataset。新行將添加到該表中,更新的信息將并入現(xiàn)有行。
若要處理可能在 update 操作過程中發(fā)生的異常,可以使用 rowupdated 事件在這些異常發(fā)生時響應(yīng)行更新錯誤(請參閱使用 dataadapter 事件),或者可以在調(diào)用 update 之前將 dataadapter.continueupdateonerror 設(shè)置為 true,然后在 update 完成時響應(yīng)存儲在特定行的 rowerror 屬性中的錯誤信息(請參閱添加和讀取行錯誤信息)。
注意 如果對 dataset、datatable 或 datarow 調(diào)用 acceptchanges,則將使某 datarow 的所有 original 值被該 datarow 的 current 值改寫。如果已修改將該行標(biāo)識為唯一行的字段值,那么當(dāng)調(diào)用 acceptchanges 后,original 值將不再匹配數(shù)據(jù)源中的值。
以下示例演示如何通過顯式設(shè)置 dataadapter 的 updatecommand 來執(zhí)行對已修改行的更新。請注意,在 update 語句的 where 子句中指定的參數(shù)設(shè)置為使用 sourcecolumn 的 original 值。這一點很重要,因為 current 值可能已被修改,并且可能不匹配數(shù)據(jù)源中的值。original 值是曾用來從數(shù)據(jù)源填充 datatable 的值。
sqlclient
[visual basic]
dim catda as sqldataadapter = new sqldataadapter("select categoryid, categoryname from categories", nwindconn)
catda.updatecommand = new sqlcommand("update categories set categoryname = @categoryname " & _
"where categoryid = @categoryid", nwindconn)
catda.updatecommand.parameters.add("@categoryname", sqldbtype.nvarchar, 15, "categoryname")
dim workparm as sqlparameter = catda.updatecommand.parameters.add("@categoryid", sqldbtype.int)
workparm.sourcecolumn = "categoryid"
workparm.sourceversion = datarowversion.original
dim catds as dataset = new dataset
catda.fill(catds, "categories")
dim crow as datarow = catds.tables("categories").rows(0)
crow("categoryname") = "new category"
catda.update(catds)
[c#]
sqldataadapter catda = new sqldataadapter("select categoryid, categoryname from categories", nwindconn);
catda.updatecommand = new sqlcommand("update categories set categoryname = @categoryname " +
"where categoryid = @categoryid" , nwindconn);
catda.updatecommand.parameters.add("@categoryname", sqldbtype.nvarchar, 15, "categoryname");
sqlparameter workparm = catda.updatecommand.parameters.add("@categoryid", sqldbtype.int);
workparm.sourcecolumn = "categoryid";
workparm.sourceversion = datarowversion.original;
dataset catds = new dataset();
catda.fill(catds, "categories");
datarow crow = catds.tables["categories"].rows[0];
crow["categoryname"] = "new category";
catda.update(catds);
oledb
[visual basic]
dim catda as oledbdataadapter = new oledbdataadapter("select categoryid, categoryname from categories", nwindconn)
catda.updatecommand = new oledbcommand("update categories set categoryname = ? " & _
"where categoryid = ?" , nwindconn)
catda.updatecommand.parameters.add("@categoryname", oledbtype.varchar, 15, "categoryname")
dim workparm as oledbparameter = catda.updatecommand.parameters.add("@categoryid", oledbtype.integer)
workparm.sourcecolumn = "categoryid"
workparm.sourceversion = datarowversion.original
dim catds as dataset = new dataset
catda.fill(catds, "categories")
dim crow as datarow = catds.tables("categories").rows(0)
crow("categoryname") = "new category"
catda.update(catds)
[c#]
oledbdataadapter catda = new oledbdataadapter("select categoryid, categoryname from categories", nwindconn);
catda.updatecommand = new oledbcommand("update categories set categoryname = ? " +
"where categoryid = ?" , nwindconn);
catda.updatecommand.parameters.add("@categoryname", oledbtype.varchar, 15, "categoryname");
oledbparameter workparm = catda.updatecommand.parameters.add("@categoryid", oledbtype.integer);
workparm.sourcecolumn = "categoryid";
workparm.sourceversion = datarowversion.original;
dataset catds = new dataset();
catda.fill(catds, "categories");
datarow crow = catds.tables["categories"].rows[0];
crow["categoryname"] = "new category";
catda.update(catds);
自動遞增列
如果來自數(shù)據(jù)源的表包含自動遞增列,則可以使用由數(shù)據(jù)源生成的值填充 dataset 中的列,方法是通過以存儲過程輸出參數(shù)的形式返回自動遞增值并將其映射到表中的一列,或者使用 dataadapter 的 rowupdated 事件。有關(guān)示例,請參閱檢索“標(biāo)識”或“自動編號”值。
但是,dataset 中的值可能會與數(shù)據(jù)源中的值不同步并導(dǎo)致意外的行為。例如,請考慮一個包含自動遞增主鍵列 customerid 的表。如果在該 dataset 中添加兩個新客戶,它們將收到自動遞增的 customerid 值 1 和 2。在向 dataadapter 的 update 方法傳遞第二個客戶行時,新添加的行會收到數(shù)據(jù)源中的自動遞增 customerid 值 1,該值與 dataset 中的值 2 不匹配。當(dāng) dataadapter 使用返回值填充 dataset 中的行時,由于第一個客戶行的 customerid 已經(jīng)是 1,因此將發(fā)生約束沖突。
為了避免這種行為,建議在使用數(shù)據(jù)源中的自動遞增列和 dataset 中的自動遞增列時,在 dataset 中創(chuàng)建 autoincrementstep 為 -1 且 autoincrementseed 為 0 的列,并確保數(shù)據(jù)源生成從 1 開始并以正步長值遞增的自動遞增標(biāo)識值。這樣,dataset 將為自動遞增值生成負(fù)數(shù),這些負(fù)數(shù)不會與數(shù)據(jù)源所生成的正自動遞增值發(fā)生沖突。另一種方法是使用 guid 類型的列而不是自動遞增列。生成 guid 值的算法在 dataset 中生成的 guid 從不會與數(shù)據(jù)源生成的 guid 相同。有關(guān)定義 datatable 中的列的更多信息,請參閱定義數(shù)據(jù)表的架構(gòu)。
插入、更新和刪除的排序
在許多情況下,以何種順序向數(shù)據(jù)源發(fā)送通過 dataset 作出的更改是相當(dāng)重要的。例如,如果已更新現(xiàn)有行的主鍵值并且添加了具有新主鍵值的新行,則務(wù)必要在處理插入之前處理更新。
可以使用 datatable 的 select 方法來返回僅引用具有特定 rowstate 的 datarow 數(shù)組。然后可以將返回的 datarow 數(shù)組傳遞到 dataadapter 的 update 方法來處理已修改的行。通過指定要更新的行的子集,可以控制處理插入、更新和刪除的順序。
例如,以下代碼確保首先處理表中已刪除的行,然后處理已更新的行,然后處理已插入的行。
[visual basic]
dim updtable as datatable = custds.tables("customers")
' first process deletes.
custda.update(updtable.select(nothing, nothing, dataviewrowstate.deleted))
' next process updates.
custda.update(updtable.select(nothing, nothing, dataviewrowstate.modifiedcurrent))
' finally, process inserts.
custda.update(updtable.select(nothing, nothing, dataviewrowstate.added))
[c#]
datatable updtable = custds.tables["customers"];
// first process deletes.
custda.update(updtable.select(null, null, dataviewrowstate.deleted));
// next process updates.
custda.update(updtable.select(null, null, dataviewrowstate.modifiedcurrent));
// finally, process inserts.
custda.update(updtable.select(null, null, dataviewrowstate.added));