巧用ADO.NET DbCommandBuilder生成命令
ADO.NET還是比較常用的,于是我研究了一下ADO.NET,在這里拿出來(lái)和大家分享一下,希望對(duì)大家有用。如果在運(yùn)行時(shí)動(dòng)態(tài)指定 SelectCommand 屬性(例如,通過(guò)接受用戶(hù)提供的文本命令的查詢(xún)工具),那么您可能無(wú)法在設(shè)計(jì)時(shí)指定適當(dāng)?shù)?InsertCommand、UpdateCommand 或 DeleteCommand。 如果您的 DataTable 映射到單個(gè)數(shù)據(jù)庫(kù)表或者是從單個(gè)數(shù)據(jù)庫(kù)表中生成的,那么您可以利用 ADO.NET DbCommandBuilder對(duì)象來(lái)自動(dòng)生成 DbDataAdapter 的 DeleteCommand、InsertCommand 和 UpdateCommand。
為了能夠自動(dòng)生成命令,必須設(shè)置 SelectCommand 屬性,這是最低要求。 由 SelectCommand 屬性檢索的表架構(gòu)確定自動(dòng)生成的 INSERT、UPDATE 和 DELETE 語(yǔ)句的語(yǔ)法。
#T#為了返回構(gòu)造 INSERT、UPDATE 和 DELETE SQL 命令所需的元數(shù)據(jù),DbCommandBuilder 必須執(zhí)行 SelectCommand。 因此,必須額外經(jīng)歷一次到數(shù)據(jù)源的過(guò)程,這可能會(huì)降低性能。若要實(shí)現(xiàn)最佳性能,請(qǐng)顯式指定命令而不是使用 ADO.NET DbCommandBuilder。SelectCommand 還必須至少返回一個(gè)主鍵或唯一列。 如果不存在任何主鍵和唯一列,則會(huì)生成 InvalidOperation 異常,并且不會(huì)生成命令。當(dāng)與 DataAdapter 關(guān)聯(lián)時(shí),ADO.NET DbCommandBuilder會(huì)自動(dòng)生成 DataAdapter 的 InsertCommand、UpdateCommand 和 DeleteCommand 屬性(如果它們?yōu)榭找茫?如果某個(gè)屬性已存在 Command,則使用現(xiàn)有 Command。
通過(guò)聯(lián)接兩個(gè)或更多個(gè)表來(lái)創(chuàng)建的數(shù)據(jù)庫(kù)視圖不會(huì)被視為單個(gè)數(shù)據(jù)庫(kù)表。 在這種情況下,您無(wú)法使用 DbCommandBuilder 來(lái)自動(dòng)生成命令;必須顯式指定命令。 有關(guān)顯式設(shè)置命令以將對(duì) DataSet 的更新解析回?cái)?shù)據(jù)源的信息,請(qǐng)參見(jiàn)使用 DataAdapter 更新數(shù)據(jù)源 (ADO.NET)。
您可能需要將輸出參數(shù)映射回 DataSet 的更新行。 一項(xiàng)常見(jiàn)的任務(wù)是從數(shù)據(jù)源中檢索自動(dòng)生成的標(biāo)識(shí)字段或時(shí)間戳的值。 默認(rèn)情況下,DbCommandBuilder 不會(huì)將輸出參數(shù)映射到更新行中的列。 在這種情況下,必須顯式指定命令。 有關(guān)將自動(dòng)生成的標(biāo)識(shí)字段映射回插入行的列的示例,請(qǐng)參見(jiàn)檢索標(biāo)識(shí)或 Autonumber 值 (ADO.NET)。
更新和刪除的開(kāi)放式并發(fā)模型
為 UPDATE 和 DELETE 語(yǔ)句自動(dòng)生成命令的邏輯基于“開(kāi)放式并發(fā)” -- 即未鎖定記錄的編輯功能,其他用戶(hù)或進(jìn)程可以隨時(shí)修改。 由于在從 SELECT 語(yǔ)句中返回某記錄之后但在發(fā)出 UPDATE 或 DELETE 語(yǔ)句之前,該記錄可能已被修改,所以自動(dòng)生成的 UPDATE 或 DELETE 語(yǔ)句包含一個(gè) WHERE 子句,指定只有在行包含所有原始值并且尚未從數(shù)據(jù)源中刪除時(shí),才會(huì)更新該行。 這樣做的目的是為了避免覆蓋新數(shù)據(jù)。當(dāng)自動(dòng)生成的 UPDATE 命令試圖更新已刪除或不包含 DataSet 中原始值的行時(shí),該命令不會(huì)影響任何記錄,并且會(huì)引發(fā) DBConcurrencyException。
如果要使 UPDATE 或 DELETE 在不考慮原始值的情況下完成,必須為 DataAdapter 顯式設(shè)置 UpdateCommand,而不依賴(lài)自動(dòng)命令生成。