您好,登錄后才能下訂單哦!
ASP.NET 2.0中怎么利用GridView批量添加數(shù)據(jù),針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
第一步:創(chuàng)建一個展示界面
我們將創(chuàng)建一個包含2個區(qū)域的單一頁面:展示區(qū)域和添加區(qū)域.我們在這一步創(chuàng)建的是展示區(qū)域,它包含一個用于展示產(chǎn)品的GridView控件以及一個標(biāo)題為“Process Product Shipment”的button按鈕.當(dāng)點擊該按鈕時,展示界面將替換為一個如圖1所示的添加界面.如果點“Add Products from Shipment” 或 “Cancel”按鈕時又會返回展示頁面.添加界面將在第二步完成.
這個包含2個界面的頁面每次只能讓一個界面可見。我們將用2個Panel Web控件作為容器包含這2個界面——一個Panel Web控件包含一個界面.
首先打開BatchData文件夾里的BatchInsert.aspx頁面,在設(shè)計器模式里從工具箱里拖一個Panel控件到頁面(如圖2所示),設(shè)置其ID為DisplayInterface.當(dāng)將Panel控件拖到頁面時其Height 和 Width屬性分別為50px 和 125px.在屬性窗口里清除這些屬性.
圖2:從工具箱里拖一個Panel控件到頁面
然后拖一個Button 和 GridView控件到Panel控件里。設(shè)Button的ID為ProcessShipment ,Text屬性為“Process Product Shipment”. 設(shè)GridView的ID為ProductsGrid,從其智能標(biāo)簽里將其綁定到一個名為ProductsDataSource的ObjectDataSource.設(shè)置該ObjectDataSource調(diào)用ProductsBLL class類的GetProducts方法.由于該GridView控件只用來展示數(shù)據(jù),從UPDATE, INSERT, DELETE標(biāo)簽里選“(None)”. 點Finish完成設(shè)置
圖3:調(diào)用ProductsBLL Class類的GetProducts方法來顯示數(shù)據(jù)
圖4:在UPDATE, INSERT, DELETE標(biāo)簽里選“(None)”
完成ObjectDataSource設(shè)置后,Visual Studio會自動地添加一些BoundFields以及一個CheckBoxField。只保留ProductName, CategoryName, SupplierName, UnitPrice, 以及Discontinued這幾列.你可以再做一些外觀的改進(jìn).我將UnitPrice列定制為貨幣值,重新對列進(jìn)行了排序,再對一些列的HeaderText值進(jìn)行了修改.再在GridView的智能標(biāo)簽里啟用了“分頁”和“排序”功能.完成上述工作后,頁面的聲明代碼看起來應(yīng)該和下面的差不多:
<asp:Panel ID="DisplayInterface" runat="server"> <p> <asp:Button ID="ProcessShipment" runat="server" Text="Process Product Shipment" /> </p> <asp:GridView ID="ProductsGrid" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ProductsDataSource"> <Columns> <asp:BoundField DataField="ProductName" HeaderText="Product" SortExpression="ProductName" /> <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True" SortExpression="CategoryName" /> <asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True" SortExpression="SupplierName" /> <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price" HtmlEncode="False" SortExpression="UnitPrice"> <ItemStyle HorizontalAlign="Right" /> </asp:BoundField> <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" SortExpression="Discontinued"> <ItemStyle HorizontalAlign="Center" /> </asp:CheckBoxField> </Columns> </asp:GridView> <asp:ObjectDataSource ID="ProductsDataSource" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts" TypeName="ProductsBLL"> </asp:ObjectDataSource> </asp:Panel>
我們注意到Button 和 GridView控件的聲明代碼出現(xiàn)在<asp:Panel>標(biāo)簽內(nèi)部,因為這些控件置于名為DisplayInterface的Panel控件里面,我們可以將Panel控件的Visible 屬性設(shè)置為false來隱藏這些控件.我們將在第三步看到,當(dāng)點擊一個按鈕時,通過編程的方式改變Panel控件的Visible屬性以顯示添加界面.
花點時間在瀏覽器里登錄該頁面.如圖5所示,你將看到一個顯示為“Process Product Shipment”的button按鈕,其下的GridView控件每次列出10個產(chǎn)品.
圖5:GridView列出了產(chǎn)品并啟用排序和分頁功能
第二步:創(chuàng)建添加界面
創(chuàng)建完展示界面后,我們將創(chuàng)建添加界面。在本教程,我們的添加界面允許用戶同時添加5個產(chǎn)品,且這5個產(chǎn)品的category 和 supplier是一樣的,而names 和 nit price值不同.在ID為DisplayInterface的Panel控件下面,從工具箱里拖一個Panel控件到頁面,設(shè)置其ID為InsertingInterface,Visible屬性為false,并清除其Height 和 Width屬性值。我們將在第三步添加代碼將其Visible屬性改為true.
接下來我們將創(chuàng)建如圖1所示的添加界面。該界面本來可以通過一些HTML技術(shù)來創(chuàng)建的,不過在這里我們將使用一個很簡單的4列7行的table表.
注意:雖然在設(shè)計器模式里可以使用工具箱的工具來添加<table> elements元素,不過那樣會自動添加一些我們不需要的style屬性設(shè)置.因此,我更偏向于在源視圖模式里添加HTML <table> elements元素. 當(dāng)寫好類<table>聲明代碼后,我喜歡立即切換到設(shè)計器模式,再添加Web控件并設(shè)置其屬性。當(dāng)心中有數(shù),已經(jīng)想好了要創(chuàng)建幾行幾列的時候,我傾向于使用靜態(tài)HTML(static HTML)而不是Table Web控件,原因是如果使用Table Web控件的話,我們必須通過FindControl("controlID")的方式來訪問放置在里面的的Web控件.不過話又說回來,如果是要創(chuàng)建一個動態(tài)變化的表(dynamically-sized tables)的話——比如該表的行和列都綁定到數(shù)據(jù)庫或者基于用戶自定義的標(biāo)準(zhǔn)格式,我還是要使用Table Web控件,原因很簡單,我們可以通過編程來創(chuàng)建該Table Web控件.
在ID為InsertingInterface的Panel控件的<asp:Panel>標(biāo)簽里輸入如下的聲明代碼:
<table class="DataWebControlStyle" cellspacing="0"> <tr class="BatchInsertHeaderRow"> <td class="BatchInsertLabel">Supplier:</td> <td></td> <td class="BatchInsertLabel">Category:</td> <td></td> </tr> <tr class="BatchInsertRow"> <td class="BatchInsertLabel">Product:</td> <td></td> <td class="BatchInsertLabel">Price:</td> <td></td> </tr> <tr class="BatchInsertAlternatingRow"> <td class="BatchInsertLabel">Product:</td> <td></td> <td class="BatchInsertLabel">Price:</td> <td></td> </tr> <tr class="BatchInsertRow"> <td class="BatchInsertLabel">Product:</td> <td></td> <td class="BatchInsertLabel">Price:</td> <td></td> </tr> <tr class="BatchInsertAlternatingRow"> <td class="BatchInsertLabel">Product:</td> <td></td> <td class="BatchInsertLabel">Price:</td> <td></td> </tr> <tr class="BatchInsertRow"> <td class="BatchInsertLabel">Product:</td> <td></td> <td class="BatchInsertLabel">Price:</td> <td></td> </tr> <tr class="BatchInsertFooterRow"> <td colspan="4"> </td> </tr> </table>
該<table>聲明代碼里暫時還未包含任何的Web控件。我們注意到每一個<tr> element元素都有明確的CSS class設(shè)置:放置名為supplier 和category的DropDownLists控件的“頭頂行”對應(yīng)的是BatchInsertHeaderRow;放置“Add Products from Shipment” 和“Cancel”按鈕的“底部行”對應(yīng)的是BatchInsertFooterRow;那些包含product和unit price的TextBox控件的行交替的運用BatchInsertRow和BatchInsertAlternatingRow.我已經(jīng)在Styles.css文件里創(chuàng)建里相應(yīng)的CSS classes,代碼如下:
/*** Styles for ~/BatchData/BatchInsert.aspx tutorial ***/ .BatchInsertLabel { font-weight: bold; text-align: right; } .BatchInsertHeaderRow td { color: White; background-color: #900; padding: 11px; } .BatchInsertFooterRow td { text-align: center; padding-top: 5px; } .BatchInsertRow { } .BatchInsertAlternatingRow { background-color: #fcc; }
輸入這些代碼后,切換到設(shè)計視圖,該<table>看起來是一個4列7行的表,如圖6所示:
圖6:添加界面為一個4列7行的表
現(xiàn)在我們在添加界面里添加Web控件.從工具箱拖2個DropDownList到表的相應(yīng)方格里——一個用來顯示supplier另一個用來顯示category.
將用來顯示supplier的那個DropDownList的ID設(shè)為Suppliers,并將其綁定到一個名為SuppliersDataSource的ObjectDataSource.設(shè)置該ObjectDataSource調(diào)用SuppliersBLL class類的GetSuppliers方法.并在UPDATE標(biāo)簽里選“(None)”,點擊Finish完成設(shè)置向?qū)?
圖7:設(shè)置ObjectDataSource調(diào)用SuppliersBLL Class類的GetSuppliers方法
設(shè)置該DropDownList顯示CompanyName列,而傳遞的值為SupplierID列.
圖8:顯示CompanyName列,傳遞的是SupplierID列的值
將第2個DropDownList的ID設(shè)為Categories,并將其綁定到一個名為CategoriesDataSource的ObjectDataSource.該ObjectDataSource調(diào)用CategoriesBLL class類的GetCategories方法. 在UPDATE標(biāo)簽里選“(None)”,再點Finish完成設(shè)置. 最后設(shè)置該DropDownList控件顯示CategoryName列,傳遞CategoryID列的值.
當(dāng)添加這2個DropDownList控件并綁定到相應(yīng)的ObjectDataSources后,你的屏幕看起來應(yīng)該和圖9差不多:
圖9:“頭部行”包含顯示Suppliers和Categories的DropDownList控件
我們現(xiàn)在需要創(chuàng)建收集每個產(chǎn)品的name和price信息的TextBox控件。在下面的每行對應(yīng)的name和price方格里各拖放一個TextBox控件. 分別設(shè)置它們的ID為ProductName1, UnitPrice1,ProductName2, UnitPrice2,依次類推.
對每個price TextBoxes添加一個CompareValidator控件,設(shè)置其ControlToValidate屬性為相應(yīng)控件的ID值.同時將Operator屬性設(shè)置為GreaterThanEqual,ValueToCompare 屬性設(shè)置為“0”, Type屬性設(shè)置為Currency.這樣一來可以保證輸入的價格為有效的大于或等于0的貨幣值.同時將Text屬性設(shè)置為“*”;ErrorMessage屬性為“The price must be greater than or equal to zero. Also, please omit any currency symbols.”。
注意:我們并沒有在添加界面里包含任何的RequiredFieldValidator控件,即便是數(shù)據(jù)庫表Products的ProductName不允許為NULL值.舉個例子,如果用戶只想在前3行輸入產(chǎn)品的name和unit price,而最后2行為空,我們就僅僅向數(shù)據(jù)庫添加了3個產(chǎn)品。由于ProductName是必需的,當(dāng)輸入了name值后,我們只需要通過編程檢查用戶是否輸入了該產(chǎn)品的unit price值.我們將在第四步進(jìn)行該檢查.
當(dāng)用戶輸入了數(shù)據(jù),但如果輸入值包含貨幣符號的話,CompareValidator控件將報告無效數(shù)據(jù).在每個unit price TextBoxe控件前添加一個“$”符合,提示用戶輸入數(shù)據(jù)的時候忽略貨幣符號.
最后,在InsertingInterface Panel控件里添加一個ValidationSummary控件,設(shè)置其ShowMessageBox屬性為true,ShowSummary屬性為false.有了這些設(shè)置后,當(dāng)用戶輸入一個無效的unit price值后,在TextBox控件旁邊將會出現(xiàn)一個星號,且ValidationSummary控件將顯示一個客戶端的消息框,顯示相應(yīng)的錯誤消息.
此時,你的屏幕看起來和圖10差不多.
圖10:添加界面現(xiàn)在包含顯示產(chǎn)品的Names和Prices的TextBox控件
接下來我們要在底部行添加“Add Products from Shipment” 和 “Cancel”按鈕.從工具箱拖2個Button控件到界面的底部,分別設(shè)置其ID為AddProducts和CancelButton;同時分別設(shè)其Text屬性為“Add Products from Shipment”和“Cancel”.此外,將 CancelButton按鈕的CausesValidation屬性設(shè)置為false.
最后,我們需要添加一個Label Web控件來顯示有關(guān)這2個界面的狀態(tài)信息.比如:當(dāng)用戶成功地添加了一批產(chǎn)品時我們希望切換到展示界面并顯示確認(rèn)消息.當(dāng)然,如果用戶輸入產(chǎn)品信息時只提供了price而沒有提供name信息,我們就需要顯示一個警告信息,提示用戶ProductName是必需的.由于我們需要顯示與這2個界面有關(guān)的信息,將該控件放在這2個Panel控件的上方.
從工具箱里拖一個Label Web控件到頁面頂部,設(shè)其ID為StatusLabel,清除其Text屬性,設(shè)其Visible屬性和EnableViewState屬性為false. 我們在以前的教程里探討過,將EnableViewState屬性設(shè)為false的話,我們可以通過編程的方式改變Label控件的屬性值,而當(dāng)發(fā)生頁面回傳時其又回到默認(rèn)狀態(tài).當(dāng)發(fā)生某些用戶行為(user action)時,會顯示狀態(tài)信息,而當(dāng)頁面回傳時,狀態(tài)信息又消失了.最后設(shè)置StatusLabel的CssClass屬性為“Warning”,這是我們在Styles.css文件里定義的CSS class名稱.
下圖顯示的是添加并設(shè)置Label控件后的樣子
圖11:在Panel控件上面放置id為StatusLabel的Label控件
第三步:在展示界面和添加界面之間切換
到此,我們已經(jīng)完成了展示和添加界面,不過我們?nèi)匀挥?個任務(wù)要做:
1.在展示界面和添加界面之間切換
2.將產(chǎn)品添加到數(shù)據(jù)庫
當(dāng)前,展示界面是可見的而添加界面是隱藏的.這是因為DisplayInterface Panel控件的Visible屬性為true(默認(rèn)值), 而InsertingInterface Panel控件的Visible屬性為false.
當(dāng)點擊“Process Product Shipment”按鈕時,我們向從展示界面切換到添加界面。為此,創(chuàng)建該按鈕的Click事件處理器,包含以下代碼:
protected void ProcessShipment_Click(object sender, EventArgs e) { DisplayInterface.Visible = false; InsertingInterface.Visible = true; }
該代碼僅僅隱藏DisplayInterface Panel而顯示InsertingInterface Panel.
接下來,我們?yōu)樘砑咏缑胬锏摹癆dd Products from Shipment”和“Cancel” 按鈕創(chuàng)建事件處理器.當(dāng)任何一個按鈕點擊時,我們需要切換到展示界面.創(chuàng)建這2個按鈕的Click事件處理器以調(diào)用ReturnToDisplayInterface方法——我們馬上就要創(chuàng)建該方法.
該方法除了隱藏InsertingInterface Panel并顯示DisplayInterface Panel外,還需要將Web控件返回到其預(yù)編輯狀態(tài)(pre-editing state).即把DropDownList控件的屬性SelectedIndex設(shè)置為0,清除TextBox控件的Text屬性.
注意:仔細(xì)思考一下,如果在返回展示界面以前,我們沒有將這些控件返回到預(yù)編輯狀態(tài)的話將會發(fā)生什么事情呢?比如用戶點擊“Process Products from Shipment”按鈕,然后輸入產(chǎn)品信息,再點“Add Products from Shipment”按鈕,這樣將添加產(chǎn)品并返回展示頁面。如果用戶又想添加另一批產(chǎn)品,一旦點擊“Process Product Shipment”按鈕時將切換到添加界面,但是DropDownList控件的值和TextBox控件的值依然是以前的值.
protected void AddProducts_Click(object sender, EventArgs e) { // TODO: Save the products // Revert to the display interface ReturnToDisplayInterface(); } protected void CancelButton_Click(object sender, EventArgs e) { // Revert to the display interface ReturnToDisplayInterface(); } const int firstControlID = 1; const int lastControlID = 5; private void ReturnToDisplayInterface() { // Reset the control values in the inserting interface Suppliers.SelectedIndex = 0; Categories.SelectedIndex = 0; for (int i = firstControlID; i <= lastControlID; i++) { ((TextBox)InsertingInterface.FindControl("ProductName" + i.ToString())).Text = string.Empty; ((TextBox)InsertingInterface.FindControl("UnitPrice" + i.ToString())).Text = string.Empty; } DisplayInterface.Visible = true; InsertingInterface.Visible = false; }
上述2個Click事件處理器都僅僅簡單的調(diào)用ReturnToDisplayInterface方法,不過我們將在第四步完善“Add Products from Shipment”的Click事件,添加代碼以保存產(chǎn)品.
ReturnToDisplayInterface方法一開始就把Suppliers和Categories的DropDownList控件返回其第一項;常量firstControlID和lastControlID分別用來設(shè)置添加界面里的標(biāo)明產(chǎn)品名稱和單價的TextBoxe控件的開始和結(jié)束索引值. 在一個for循環(huán)里設(shè)置這些控件的Text屬性為空字符串.最后重新設(shè)置Panels控件的Visible屬性,以顯示展示界面而隱藏添加界面.
花點時間在瀏覽器里測試該頁面,當(dāng)首次登錄時你將看到如圖5所示的畫面,點“Process Product Shipment”按鈕,頁面將回傳并切換到如圖12所示的添加界面,不管點“Add Products from Shipment”還是“Cancel”按鈕都將返回展示界面.
注意:當(dāng)瀏覽添加界面時,測試一下與unit price TextBox對應(yīng)的驗證控件。如果你輸入的不是貨幣值或價格比0小,當(dāng)點擊“Add Products from Shipment”按鈕時,就會彈出一個客戶端的警告消息.
圖12:點擊Process Product Shipment” 按鈕后,將切換到添加界面.
第四步:添加產(chǎn)品
剩下要做的事情是在“Add Products from Shipment”按鈕的Click事件處理器里將產(chǎn)品添加到數(shù)據(jù)庫.為此,我們可以創(chuàng)建一個ProductsDataTable,并為要插入的產(chǎn)品添加一個ProductsRow instance實例。一旦添加完P(guān)roductsRows后,我們就調(diào)用并把ProductsDataTable傳遞給ProductsBLL class類的UpdateWithTransaction方法.記得我們是在第61章《在事務(wù)里對數(shù)據(jù)庫修改進(jìn)行封裝》里創(chuàng)建的UpdateWithTransaction方法,該方法將ProductsDataTable傳遞給ProductsTableAdapter的UpdateWithTransaction方法.于是啟動一個ADO.NET事務(wù),TableAdatper針對添加的每一個ProductsRow向數(shù)據(jù)庫發(fā)出一個INSERT命令.如果所有的添加無誤則提交事務(wù),否則對事務(wù)回滾.
對“Add Products from Shipment”按鈕的Click處理器進(jìn)行編碼時,應(yīng)該執(zhí)行一些誤差校驗,因為我們沒有在添加界面里使用RequiredFieldValidators控件,某個用戶可能輸入了產(chǎn)品的price而忽視里其name。由于產(chǎn)品的name是必須的,如果出現(xiàn)這種情況的話,我們需要提醒用戶并中斷inserts操作.完整的代碼如下:
protected void AddProducts_Click(object sender, EventArgs e) { // Make sure that the UnitPrice CompareValidators report valid data... if (!Page.IsValid) return; // Add new ProductsRows to a ProductsDataTable... Northwind.ProductsDataTable products = new Northwind.ProductsDataTable(); for (int i = firstControlID; i <= lastControlID; i++) { // Read in the values for the product name and unit price string productName = ((TextBox)InsertingInterface.FindControl ("ProductName" + i.ToString())).Text.Trim(); string unitPrice = ((TextBox)InsertingInterface.FindControl ("UnitPrice" + i.ToString())).Text.Trim(); // Ensure that if unitPrice has a value, so does productName if (unitPrice.Length > 0 && productName.Length == 0) { // Display a warning and exit this event handler StatusLabel.Text = "If you provide a unit price you must also " + "include the name of the product."; StatusLabel.Visible = true; return; } // Only add the product if a product name value is provided if (productName.Length > 0) { // Add a new ProductsRow to the ProductsDataTable Northwind.ProductsRow newProduct = products.NewProductsRow(); // Assign the values from the web page newProduct.ProductName = productName; newProduct.SupplierID = Convert.ToInt32(Suppliers.SelectedValue); newProduct.CategoryID = Convert.ToInt32(Categories.SelectedValue); if (unitPrice.Length > 0) newProduct.UnitPrice = Convert.ToDecimal(unitPrice); // Add any "default" values newProduct.Discontinued = false; newProduct.UnitsOnOrder = 0; products.AddProductsRow(newProduct); } } // If we reach here, see if there were any products added if (products.Count > 0) { // Add the new products to the database using a transaction ProductsBLL productsAPI = new ProductsBLL(); productsAPI.UpdateWithTransaction(products); // Rebind the data to the grid so that the producst just added are displayed ProductsGrid.DataBind(); // Display a confirmation (don't use the Warning CSS class, though) StatusLabel.CssClass = string.Empty; StatusLabel.Text = string.Format( "{0} products from supplier {1} have been added and filed under " + "category {2}.", products.Count, Suppliers.SelectedItem.Text, Categories.SelectedItem.Text); StatusLabel.Visible = true; // Revert to the display interface ReturnToDisplayInterface(); } else { // No products supplied! StatusLabel.Text = "No products were added. Please enter the product " + "names and unit prices in the textboxes."; StatusLabel.Visible = true; } }
該事件處理器開始時檢查Page.IsValid屬性返回的值是否為true。如果返回的為false,那就意味著至少有一個CompareValidators控件發(fā)現(xiàn)了無效的數(shù)據(jù).此時,我們要么停止添加產(chǎn)品;要么將用戶鍵入的unit price值向ProductsRow的UnitPrice屬性賦值時,以拋出一個異常告終.
接下來創(chuàng)建一個新的ProductsDataTable instance實例(也就是products),在一個for循環(huán)里遍歷有關(guān)name和unit price的TextBox控件,并將其Text屬性讀取到局部變量productName 和 unitPrice里.如果用戶輸入了產(chǎn)品的unit price值而沒有輸入產(chǎn)品的name值,那么StatusLabel控件就會顯示消息“If you provide a unit price you must also include the name of the product”并退出事件處理器.
如果用戶輸入了產(chǎn)品name的話,就用ProductsDataTable的NewProductsRow方法創(chuàng)建一個新的ProductsRow instance實例.對實例的ProductName屬性而言,是用相應(yīng)的TextBox來賦值;而對SupplierID 和 CategoryID屬性而言,是用添加界面頂部的相應(yīng)的DropDownList控件的SelectedValue屬性值來賦值的;如果用戶輸入里產(chǎn)品的價格,就對ProductsRow instance實例的UnitPrice屬性進(jìn)行賦值,如果用戶沒有輸入價格那么就置空,向數(shù)據(jù)庫添加數(shù)據(jù)時UnitPrice的值就為NULL值.最后,對Discontinued 和 UnitsOnOrder屬性用硬編碼的值“false”和“0”分別賦值.
完成對ProductsRow instance實例的相關(guān)屬性賦值后,將其添加到ProductsDataTable.
完成for循環(huán)后我們將檢查是否已經(jīng)添加了產(chǎn)品.畢竟,用戶可能沒有輸入任何的信息就點擊了“Add Products from Shipment”按鈕.如果在ProductsDataTable里至少存在一個產(chǎn)品,將調(diào)用ProductsBLL class類的UpdateWithTransaction方法,接下來對名為ProductsGrid的GridView控件重新進(jìn)行綁定,最新添加的產(chǎn)品就會出現(xiàn)在出現(xiàn)在展示界面里.StatusLabel將被更新以顯示一個確認(rèn)消息,然后調(diào)用ReturnToDisplayInterface,隱藏添加界面而顯示展示界面.
如果沒有添加任何產(chǎn)品,添加界面照樣會隱藏,不過會顯示一個消息“No products were added. Please enter the product names and unit prices in the textboxes”.
圖13顯示的情況是用戶輸入了unit price值而沒有輸入相應(yīng)的產(chǎn)品name;圖14顯示的是成功添加3個產(chǎn)品后的展示界面.圖15顯示的是其中2個產(chǎn)品的界面(還有1個在前面那一頁)
圖13:當(dāng)輸入Unit Price值,產(chǎn)品的Name也是必需的
圖14:添加了3個由供應(yīng)商Mayumi提供的Veggies類產(chǎn)品
圖15:新添加的產(chǎn)品可以在GridView里的最后一頁找到
注意:本文使用的批添加邏輯將insert封裝在一個事務(wù)里.要證實的話,我們可以有意的導(dǎo)入一個數(shù)據(jù)庫級的錯誤(database-level error).比如:對ProductsRow instance實例的 CategoryID屬性而言,我們不像上面那樣用Categories DropDownList控件的selected值來賦值,而是用i * 5對其賦值.這里的i是指介于1到5之間的循環(huán)索引值(loop indexer).因此,當(dāng)添加2個或更多的產(chǎn)品時,第一個產(chǎn)品的CategoryID值(5)是有效的,而后面的產(chǎn)品的CategoryID值就無效了,因為其值與表Categories里的CategoryID值不匹配(譯注:因為第2個產(chǎn)品的CategoryID值為10;第3個的為15,依次類推).后果是第一個產(chǎn)品的INSERT操作成功,后面的操作失敗,因為違反了外鍵約束.由于我們的該批添加是原子操作,第一個INSERT會回滾,數(shù)據(jù)庫就會返回到開始批添加前的狀態(tài)
結(jié)語:
在本文及前2章,我們創(chuàng)建里對數(shù)據(jù)進(jìn)行批更新、批刪除、批添加的界面.這些界面都用到了事務(wù)。該事務(wù),我們是在第61章《在事務(wù)里對數(shù)據(jù)庫修改進(jìn)行封裝》里在數(shù)據(jù)訪問層Data Access Layer里添加的.在某些情況下,這些批數(shù)據(jù)處理界面可以極大的提升最終用戶的效率.
對處理批數(shù)據(jù)的考察到此為止.接下來的系列文章里我們將考察Data Access Layer數(shù)據(jù)訪問層里的多種更高級的情況。包括在TableAdapter的方法里使用存儲過程、在DAL里進(jìn)行連接和命令級(connection- and command-level)的設(shè)置、對連接字符串進(jìn)行加密等.
關(guān)于ASP.NET 2.0中怎么利用GridView批量添加數(shù)據(jù)問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。