ASP.NET 2.0數(shù)據(jù)教程:插入,更新和刪除數(shù)據(jù)
ASP.NET 2.0數(shù)據(jù)教程第四步:插入,更新和刪除數(shù)據(jù)
ASP.NET 2.0中常用的插入,更新和刪除數(shù)據(jù)的模式有兩種。***種模式,我稱(chēng)之為DB直接模式,涉及的方法被調(diào)用時(shí),會(huì)向數(shù)據(jù)庫(kù)里發(fā)出一個(gè)INSERT, 或UPDATE,或DELETE命令,這個(gè)命令只對(duì)單個(gè)數(shù)據(jù)庫(kù)記錄做操作。象這樣的方法一般接受一系列對(duì)應(yīng)于插入,更新或刪除的值的標(biāo)量參數(shù)(譬如整數(shù),字符串,布爾值,日期時(shí)間等)。譬如,用這個(gè)模式來(lái)操作Products表的話(huà),刪除方法會(huì)接受一個(gè)整數(shù)參數(shù),代表所需要?jiǎng)h除的記錄的ProductID,而插入方法則會(huì)接受一個(gè)對(duì)應(yīng)于ProductName的字符串,對(duì)應(yīng) 于UnitPrice的decimal值,對(duì)應(yīng)于UnitsOnStock的整數(shù)等等。
圖 21: 每個(gè)插入,更新,和刪除請(qǐng)求都被立刻發(fā)送到數(shù)據(jù)庫(kù)
另外一個(gè)模式,我稱(chēng)之為批更新模式,可以在一個(gè)方法調(diào)用里更新整個(gè)DataSet,或者整個(gè)DataTable,或 者一個(gè)DataRow集合。在這個(gè)模式里,開(kāi)發(fā)人員在一個(gè)DataTable中刪除,插入,修改DataRow,然后把這 些DataRow或整個(gè)DataTable傳給一個(gè)更新方法。然后這個(gè)方法會(huì)輪循傳入的DataRow們,通過(guò)DataRow的RowState屬 性屬性來(lái)決定這些DataRow是否被改動(dòng)過(guò),或是新記錄,或是被刪除的記錄,然后為每個(gè)記錄發(fā)出合適的數(shù)據(jù)庫(kù)命令。
圖 22: 在Update 方法調(diào)用之后,所有的變動(dòng)都與數(shù)據(jù)庫(kù)同步了
在ASP.NET 2.0默認(rèn)情形下,TableAdapter采用批更新模式,但也支持DB直接模式。因?yàn)槲覀冊(cè)趧?chuàng)建我們的TableAdapter時(shí)的高級(jí)選項(xiàng)中選擇了“生成插入,更新,和刪除語(yǔ)句” 這個(gè)選項(xiàng),ProductsTableAdapter 包含了一個(gè) Update()方法,該方法實(shí)現(xiàn)了批更新模式。具體地說(shuō),TableAdapter包含了一個(gè)Update() 方法,可以傳入一個(gè)強(qiáng)類(lèi)型 的DataSet,或者一個(gè)強(qiáng)類(lèi)型的DataTable,或者一個(gè)和多個(gè)DataRow。假如你在一開(kāi)始創(chuàng)建TableAdapter時(shí)的選項(xiàng)中沒(méi)有清除“生成DB直接方法(GenerateDBDirectMethods)”復(fù)選框的話(huà),DB直接模 式也會(huì)通過(guò)Insert(),Update()和Delete()方法來(lái)實(shí)現(xiàn)。
這兩種數(shù)據(jù)修改模式都使用了TableAdapter的InsertCommand,UpdateCommand, 和DeleteCommand屬性來(lái)向數(shù)據(jù)庫(kù)發(fā)出對(duì)應(yīng)的INSERT,UPDATE和DELETE命令。你可以在DataSet設(shè)計(jì)器里點(diǎn)擊TableAdapter,然后在屬性窗口查看和改 動(dòng)InsertCommand,UpdateCommand, 和DeleteCommand屬性。(確認(rèn)你選擇了TableAdapter,并且ProductsTableAdapter對(duì)象是屬性窗口中下拉框里被選中的項(xiàng))
圖23: TableAdapter包含InsertCommand,UpdateCommand, 和DeleteCommand等屬性
想查看或改動(dòng)這些數(shù)據(jù)庫(kù)命令的屬性的話(huà),點(diǎn)擊CommandText子屬性,這會(huì)啟動(dòng)對(duì)應(yīng)的查詢(xún)生成器。
圖 24: 在查詢(xún)生成器里配置插入,更新,刪除語(yǔ)句
下面的編碼例子示范了如何使用批更新模式來(lái)把沒(méi)被終止的,且?guī)齑娴扔诨蛏儆?5個(gè)單元的產(chǎn)品的價(jià)格加倍:
- NorthwindTableAdapters.ProductsTableAdapter
- productsAdapter =
- new NorthwindTableAdapters.ProductsTableAdapter();
- // For each product, double its price if it is not discontinued
- and
- // there are 25 items in stock or less
- Northwind.ProductsDataTable products = productsAdapter.GetProducts();
- foreach (Northwind.ProductsRow product in products)
- if (!product.Discontinued && product.UnitsInStock
- < = 25)
- product.UnitPrice *= 2;
- // Update the products
- productsAdapter.Update(products);
下面的編碼示范如何使用DB直接模式刪除一個(gè)產(chǎn)品,更新一個(gè)產(chǎn)品,然后添加一個(gè)新的產(chǎn)品:
C#
- NorthwindTableAdapters.ProductsTableAdapter
- productsAdapter = new
- NorthwindTableAdapters.ProductsTableAdapter();
- // Delete the product with ProductID 3
- productsAdapter.Delete(3);
- // Update Chai (ProductID of 1), setting the UnitsOnOrder to
- 15
- productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
- 18.0m, 39, 15, 10, false, 1);
- // Add a new product
- productsAdapter.Insert("New Product", 1, 1,
- "12 tins per carton", 14.95m, 15, 0, 10, false);
創(chuàng)建自定義的插入,更新,刪除方法
用DB直接法生成的Insert(), Update(),和Delete()方法有時(shí) 候會(huì)感覺(jué)有點(diǎn)不方便,特別是當(dāng)數(shù)據(jù)表有許多字段的時(shí)候。看一下前面這個(gè)編碼例子,沒(méi)有IntelliSense的幫助的話(huà),不是很清楚Products表的哪個(gè)字段對(duì)應(yīng)Update()和Insert()方法中的哪個(gè)輸入?yún)?shù)。有時(shí)候我們只要更新一到二個(gè)字 段或者需要一個(gè)自定義的Insert()方法,這個(gè)方法需要返回剛插入的記錄 的IDENTITY(自增)的字段值。
要?jiǎng)?chuàng)建這樣的自定義方法,回到DataSet設(shè)計(jì)器。在TableAdapter上按右鼠標(biāo),選擇“添加查詢(xún)”,然后回 到TableAdapter配置向?qū)?。在第二屏上,我們可以指明要生成的查?xún)的類(lèi)型。讓我們生成一個(gè)添加新 的product(產(chǎn)品)記錄,然后返回新添加記錄的ProductID值的方法。因此,選擇生成一個(gè)插入(INSERT)型查詢(xún)。
圖25: 創(chuàng)建一個(gè)給Products表添加新記錄的方法
下一個(gè)屏顯示InsertCommand的CommandText屬性。在查詢(xún)語(yǔ)句后面,增添一個(gè)SELECT SCOPE_IDENTITY()的查詢(xún),這查詢(xún)將返回當(dāng)前同一個(gè)操作范圍內(nèi)插 入IDENTITY字段的***那個(gè)identity 值。(詳見(jiàn)技術(shù)文檔中關(guān) 于SCOPE_IDENTITY()的內(nèi)容以及為什么你應(yīng)該http://weblogs.sqlteam.com/travisl/archive/2003/10/29/405.aspx)。確認(rèn)在添加SELECT語(yǔ)句前,你在INSERT語(yǔ)句后面添一個(gè)分號(hào) 。
圖26: 增添查詢(xún)返回SCOPE_IDENTITY()值
***,把這個(gè)新方法命名為InsertProduct。
圖 27:放方法名字設(shè)成InsertProduct
當(dāng)你返回DataSet設(shè)計(jì)器時(shí),你將看到ProductsTableAdapter多了一個(gè)新的方法,InsertProduct。如果對(duì)應(yīng)Products表的每個(gè)字段,這個(gè)新的方法沒(méi)有對(duì)應(yīng)的參數(shù)的話(huà),非??赡艿脑蚴牵阃私oINSERT語(yǔ)句的結(jié)尾添加一個(gè)分號(hào)(semi-colon)。重新配 置InsertProduct方法,確認(rèn)在INSERT和SELECT語(yǔ)句間有個(gè)分號(hào)。
在ASP.NET 2.0的默認(rèn)情形下,插入方法調(diào)用的是非查詢(xún)(non-query)方法,意即,他們只返回受影響的記錄數(shù)。但是,我們想要讓InsertProduct方法返回一個(gè)查詢(xún)返回的值,而不是受影響的記錄數(shù)。這可以把InsertProduct方法的ExecuteMode屬性改成Scalar(標(biāo)量)來(lái)實(shí)現(xiàn)。
圖 28:把ExecuteMode屬性改成Scalar
下面的編碼示范如何使用這個(gè)新的InsertProduct方法:
C#
- NorthwindTableAdapters.ProductsTableAdapter
- productsAdapter = new
- NorthwindTableAdapters.ProductsTableAdapter();
- // Add a new product
- int new_productID =
- Convert.ToInt32(productsAdapter.InsertProduct("New
- Product", 1, 1, "12 tins per carton",
- 14.95m, 10, 0, 10, false));
- // On second thought, delete the product
- productsAdapter.Delete(new_productID);
【編輯推薦】