成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > 在ASP.NET 2.0中操作數(shù)據(jù)之六十四:GridView批量添加數(shù)據(jù)

在ASP.NET 2.0中操作數(shù)據(jù)之六十四:GridView批量添加數(shù)據(jù)

熱門標(biāo)簽:網(wǎng)絡(luò)電話外呼系統(tǒng)上海 百應(yīng)電話機(jī)器人外呼系統(tǒng) 400電話辦理怎么樣 蘇州如何辦理400電話 西寧呼叫中心外呼系統(tǒng)線路商 聯(lián)通官網(wǎng)400電話辦理 地圖標(biāo)注軟件免費(fèi)下載 外呼電話機(jī)器人成本 臨沂智能電話機(jī)器人加盟

導(dǎo)言:

  在前面的第62章《GridView批量更新數(shù)據(jù)》里,我們用GridView控件里定制了一個(gè)批編輯界面,同樣的我們也可以定制一個(gè)批添加界面.假設(shè)有這種情況,我們接受一批從Tokyo(東京)發(fā)過來的貨物:6種不同的tea 和 coffee,如果用戶在一個(gè)DetailsView控件里一次輸入一個(gè)產(chǎn)品,他將會(huì)重復(fù)的輸入很多相同的值,比如相同的種類(Beverages),相同的供應(yīng)商(Tokyo Traders),相同的discontinued值(False),以及相同的order值(0).重復(fù)性的輸入這些相同的值不僅累,還很容易出錯(cuò).只需額外多做一些工作,我們就可以創(chuàng)建一個(gè)批添加界面。用戶只需一次行的選擇supplier 和category,輸入一系列產(chǎn)品的names 和unit prices,再點(diǎn)擊一個(gè)按鈕就可以將這些新產(chǎn)品添加進(jìn)數(shù)據(jù)庫(如圖1所示).這些添加的產(chǎn)品的ProductName 和UnitPrice數(shù)據(jù)由界面上方的2個(gè)DropDownList控件指定,Discontinued 和UnitsOnOrder的值由“硬編輯”指定,分別為false和0.


圖1:批添加界面


本教程,我們將創(chuàng)建一個(gè)如圖1所示的批添加界面。在前面2章的基礎(chǔ)上我們將把添加過程用事務(wù)封裝以保證原子操作.讓我們開始吧!

第一步:創(chuàng)建一個(gè)展示界面

  我們將創(chuàng)建一個(gè)包含2個(gè)區(qū)域的單一頁面:展示區(qū)域和添加區(qū)域.我們在這一步創(chuàng)建的是展示區(qū)域,它包含一個(gè)用于展示產(chǎn)品的GridView控件以及一個(gè)標(biāo)題為“Process Product Shipment”的button按鈕.當(dāng)點(diǎn)擊該按鈕時(shí),展示界面將替換為一個(gè)如圖1所示的添加界面.如果點(diǎn)“Add Products from Shipment” 或 “Cancel”按鈕時(shí)又會(huì)返回展示頁面.添加界面將在第二步完成.

  這個(gè)包含2個(gè)界面的頁面每次只能讓一個(gè)界面可見。我們將用2個(gè)Panel Web控件作為容器包含這2個(gè)界面——一個(gè)Panel Web控件包含一個(gè)界面.

  首先打開BatchData文件夾里的BatchInsert.aspx頁面,在設(shè)計(jì)器模式里從工具箱里拖一個(gè)Panel控件到頁面(如圖2所示),設(shè)置其ID為DisplayInterface.當(dāng)將Panel控件拖到頁面時(shí)其Height 和 Width屬性分別為50px 和 125px.在屬性窗口里清除這些屬性.


圖2:從工具箱里拖一個(gè)Panel控件到頁面

  然后拖一個(gè)Button 和 GridView控件到Panel控件里。設(shè)Button的ID為ProcessShipment ,Text屬性為“Process Product Shipment”.  設(shè)GridView的ID為ProductsGrid,從其智能標(biāo)簽里將其綁定到一個(gè)名為ProductsDataSource的ObjectDataSource.設(shè)置該ObjectDataSource調(diào)用ProductsBLL class類的GetProducts方法.由于該GridView控件只用來展示數(shù)據(jù),從UPDATE, INSERT, DELETE標(biāo)簽里選“(None)”. 點(diǎn)Finish完成設(shè)置


圖3:調(diào)用ProductsBLL Class類的GetProducts方法來顯示數(shù)據(jù)


圖4:在UPDATE, INSERT, DELETE標(biāo)簽里選“(None)”

  完成ObjectDataSource設(shè)置后,Visual Studio會(huì)自動(dòng)地添加一些BoundFields以及一個(gè)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)部,因?yàn)檫@些控件置于名為DisplayInterface的Panel控件里面,我們可以將Panel控件的Visible 屬性設(shè)置為false來隱藏這些控件.我們將在第三步看到,當(dāng)點(diǎn)擊一個(gè)按鈕時(shí),通過編程的方式改變Panel控件的Visible屬性以顯示添加界面.

  花點(diǎn)時(shí)間在瀏覽器里登錄該頁面.如圖5所示,你將看到一個(gè)顯示為“Process Product Shipment”的button按鈕,其下的GridView控件每次列出10個(gè)產(chǎn)品.


圖5:GridView列出了產(chǎn)品并啟用排序和分頁功能

第二步:創(chuàng)建添加界面

  創(chuàng)建完展示界面后,我們將創(chuàng)建添加界面。在本教程,我們的添加界面允許用戶同時(shí)添加5個(gè)產(chǎn)品,且這5個(gè)產(chǎn)品的category 和 supplier是一樣的,而names 和 nit price值不同.在ID為DisplayInterface的Panel控件下面,從工具箱里拖一個(gè)Panel控件到頁面,設(shè)置其ID為InsertingInterface,Visible屬性為false,并清除其Height 和 Width屬性值。我們將在第三步添加代碼將其Visible屬性改為true.

  接下來我們將創(chuàng)建如圖1所示的添加界面。該界面本來可以通過一些HTML技術(shù)來創(chuàng)建的,不過在這里我們將使用一個(gè)很簡單的4列7行的table表.

  注意:雖然在設(shè)計(jì)器模式里可以使用工具箱的工具來添加table> elements元素,不過那樣會(huì)自動(dòng)添加一些我們不需要的style屬性設(shè)置.因此,我更偏向于在源視圖模式里添加HTML table> elements元素. 當(dāng)寫好類table>聲明代碼后,我喜歡立即切換到設(shè)計(jì)器模式,再添加Web控件并設(shè)置其屬性。當(dāng)心中有數(shù),已經(jīng)想好了要?jiǎng)?chuàng)建幾行幾列的時(shí)候,我傾向于使用靜態(tài)HTML(static HTML)而不是Table Web控件,原因是如果使用Table Web控件的話,我們必須通過FindControl("controlID")的方式來訪問放置在里面的的Web控件.不過話又說回來,如果是要?jiǎng)?chuàng)建一個(gè)動(dò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>聲明代碼里暫時(shí)還未包含任何的Web控件。我們注意到每一個(gè)tr> element元素都有明確的CSS class設(shè)置:放置名為supplier 和category的DropDownLists控件的“頭頂行”對應(yīng)的是BatchInsertHeaderRow;放置“Add Products from Shipment” 和“Cancel”按鈕的“底部行”對應(yīng)的是BatchInsertFooterRow;那些包含product和unit price的TextBox控件的行交替的運(yùn)用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è)計(jì)視圖,該table>看起來是一個(gè)4列7行的表,如圖6所示:


圖6:添加界面為一個(gè)4列7行的表

  現(xiàn)在我們在添加界面里添加Web控件.從工具箱拖2個(gè)DropDownList到表的相應(yīng)方格里——一個(gè)用來顯示supplier另一個(gè)用來顯示category.

  將用來顯示supplier的那個(gè)DropDownList的ID設(shè)為Suppliers,并將其綁定到一個(gè)名為SuppliersDataSource的ObjectDataSource.設(shè)置該ObjectDataSource調(diào)用SuppliersBLL class類的GetSuppliers方法.并在UPDATE標(biāo)簽里選“(None)”,點(diǎn)擊Finish完成設(shè)置向?qū)?


圖7:設(shè)置ObjectDataSource調(diào)用SuppliersBLL Class類的GetSuppliers方法

設(shè)置該DropDownList顯示CompanyName列,而傳遞的值為SupplierID列.


圖8:顯示CompanyName列,傳遞的是SupplierID列的值

  將第2個(gè)DropDownList的ID設(shè)為Categories,并將其綁定到一個(gè)名為CategoriesDataSource的ObjectDataSource.該ObjectDataSource調(diào)用CategoriesBLL class類的GetCategories方法. 在UPDATE標(biāo)簽里選“(None)”,再點(diǎn)Finish完成設(shè)置. 最后設(shè)置該DropDownList控件顯示CategoryName列,傳遞CategoryID列的值.

當(dāng)添加這2個(gè)DropDownList控件并綁定到相應(yīng)的ObjectDataSources后,你的屏幕看起來應(yīng)該和圖9差不多:


圖9:“頭部行”包含顯示Suppliers和Categories的DropDownList控件

  我們現(xiàn)在需要?jiǎng)?chuàng)建收集每個(gè)產(chǎn)品的name和price信息的TextBox控件。在下面的每行對應(yīng)的name和price方格里各拖放一個(gè)TextBox控件. 分別設(shè)置它們的ID為ProductName1, UnitPrice1,ProductName2, UnitPrice2,依次類推.

  對每個(gè)price TextBoxes添加一個(gè)CompareValidator控件,設(shè)置其ControlToValidate屬性為相應(yīng)控件的ID值.同時(shí)將Operator屬性設(shè)置為GreaterThanEqual,ValueToCompare 屬性設(shè)置為“0”, Type屬性設(shè)置為Currency.這樣一來可以保證輸入的價(jià)格為有效的大于或等于0的貨幣值.同時(shí)將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值.舉個(gè)例子,如果用戶只想在前3行輸入產(chǎn)品的name和unit price,而最后2行為空,我們就僅僅向數(shù)據(jù)庫添加了3個(gè)產(chǎn)品。由于ProductName是必需的,當(dāng)輸入了name值后,我們只需要通過編程檢查用戶是否輸入了該產(chǎn)品的unit price值.我們將在第四步進(jìn)行該檢查.

  當(dāng)用戶輸入了數(shù)據(jù),但如果輸入值包含貨幣符號的話,CompareValidator控件將報(bào)告無效數(shù)據(jù).在每個(gè)unit price TextBoxe控件前添加一個(gè)“$”符合,提示用戶輸入數(shù)據(jù)的時(shí)候忽略貨幣符號.

  最后,在InsertingInterface Panel控件里添加一個(gè)ValidationSummary控件,設(shè)置其ShowMessageBox屬性為true,ShowSummary屬性為false.有了這些設(shè)置后,當(dāng)用戶輸入一個(gè)無效的unit price值后,在TextBox控件旁邊將會(huì)出現(xiàn)一個(gè)星號,且ValidationSummary控件將顯示一個(gè)客戶端的消息框,顯示相應(yīng)的錯(cuò)誤消息.

  此時(shí),你的屏幕看起來和圖10差不多.


圖10:添加界面現(xiàn)在包含顯示產(chǎn)品的Names和Prices的TextBox控件

  接下來我們要在底部行添加“Add Products from Shipment” 和 “Cancel”按鈕.從工具箱拖2個(gè)Button控件到界面的底部,分別設(shè)置其ID為AddProducts和CancelButton;同時(shí)分別設(shè)其Text屬性為“Add Products from Shipment”和“Cancel”.此外,將 CancelButton按鈕的CausesValidation屬性設(shè)置為false.

  最后,我們需要添加一個(gè)Label Web控件來顯示有關(guān)這2個(gè)界面的狀態(tài)信息.比如:當(dāng)用戶成功地添加了一批產(chǎn)品時(shí)我們希望切換到展示界面并顯示確認(rèn)消息.當(dāng)然,如果用戶輸入產(chǎn)品信息時(shí)只提供了price而沒有提供name信息,我們就需要顯示一個(gè)警告信息,提示用戶ProductName是必需的.由于我們需要顯示與這2個(gè)界面有關(guān)的信息,將該控件放在這2個(gè)Panel控件的上方.

  從工具箱里拖一個(gè)Label Web控件到頁面頂部,設(shè)其ID為StatusLabel,清除其Text屬性,設(shè)其Visible屬性和EnableViewState屬性為false. 我們在以前的教程里探討過,將EnableViewState屬性設(shè)為false的話,我們可以通過編程的方式改變Label控件的屬性值,而當(dāng)發(fā)生頁面回傳時(shí)其又回到默認(rèn)狀態(tài).當(dāng)發(fā)生某些用戶行為(user action)時(shí),會(huì)顯示狀態(tài)信息,而當(dāng)頁面回傳時(shí),狀態(tài)信息又消失了.最后設(shè)置StatusLabel的CssClass屬性為“Warning”,這是我們在Styles.css文件里定義的CSS class名稱.

下圖顯示的是添加并設(shè)置Label控件后的樣子


圖11:在Panel控件上面放置id為StatusLabel的Label控件

第三步:在展示界面和添加界面之間切換

到此,我們已經(jīng)完成了展示和添加界面,不過我們?nèi)匀挥?個(gè)任務(wù)要做:

1.在展示界面和添加界面之間切換
2.將產(chǎn)品添加到數(shù)據(jù)庫

當(dāng)前,展示界面是可見的而添加界面是隱藏的.這是因?yàn)镈isplayInterface Panel控件的Visible屬性為true(默認(rèn)值), 而InsertingInterface Panel控件的Visible屬性為false.

當(dāng)點(diǎn)擊“Process Product Shipment”按鈕時(shí),我們向從展示界面切換到添加界面。為此,創(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)任何一個(gè)按鈕點(diǎn)擊時(shí),我們需要切換到展示界面.創(chuàng)建這2個(gè)按鈕的Click事件處理器以調(diào)用ReturnToDisplayInterface方法——我們馬上就要?jiǎng)?chuàng)建該方法.

  該方法除了隱藏InsertingInterface Panel并顯示DisplayInterface Panel外,還需要將Web控件返回到其預(yù)編輯狀態(tài)(pre-editing state).即把DropDownList控件的屬性SelectedIndex設(shè)置為0,清除TextBox控件的Text屬性.

  注意:仔細(xì)思考一下,如果在返回展示界面以前,我們沒有將這些控件返回到預(yù)編輯狀態(tài)的話將會(huì)發(fā)生什么事情呢?比如用戶點(diǎn)擊“Process Products from Shipment”按鈕,然后輸入產(chǎn)品信息,再點(diǎn)“Add Products from Shipment”按鈕,這樣將添加產(chǎn)品并返回展示頁面。如果用戶又想添加另一批產(chǎn)品,一旦點(diǎn)擊“Process Product Shipment”按鈕時(shí)將切換到添加界面,但是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個(gè)Click事件處理器都僅僅簡單的調(diào)用ReturnToDisplayInterface方法,不過我們將在第四步完善“Add Products from Shipment”的Click事件,添加代碼以保存產(chǎn)品.

  ReturnToDisplayInterface方法一開始就把Suppliers和Categories的DropDownList控件返回其第一項(xiàng);常量firstControlID和lastControlID分別用來設(shè)置添加界面里的標(biāo)明產(chǎn)品名稱和單價(jià)的TextBoxe控件的開始和結(jié)束索引值. 在一個(gè)for循環(huán)里設(shè)置這些控件的Text屬性為空字符串.最后重新設(shè)置Panels控件的Visible屬性,以顯示展示界面而隱藏添加界面.

  花點(diǎn)時(shí)間在瀏覽器里測試該頁面,當(dāng)首次登錄時(shí)你將看到如圖5所示的畫面,點(diǎn)“Process Product Shipment”按鈕,頁面將回傳并切換到如圖12所示的添加界面,不管點(diǎn)“Add Products from Shipment”還是“Cancel”按鈕都將返回展示界面.

  注意:當(dāng)瀏覽添加界面時(shí),測試一下與unit price TextBox對應(yīng)的驗(yàn)證控件。如果你輸入的不是貨幣值或價(jià)格比0小,當(dāng)點(diǎn)擊“Add Products from Shipment”按鈕時(shí),就會(huì)彈出一個(gè)客戶端的警告消息.


圖12:點(diǎn)擊Process Product Shipment” 按鈕后,將切換到添加界面.

第四步:添加產(chǎn)品

  剩下要做的事情是在“Add Products from Shipment”按鈕的Click事件處理器里將產(chǎn)品添加到數(shù)據(jù)庫.為此,我們可以創(chuàng)建一個(gè)ProductsDataTable,并為要插入的產(chǎn)品添加一個(gè)ProductsRow instance實(shí)例。一旦添加完P(guān)roductsRows后,我們就調(diào)用并把ProductsDataTable傳遞給ProductsBLL class類的UpdateWithTransaction方法.記得我們是在第61章《在事務(wù)里對數(shù)據(jù)庫修改進(jìn)行封裝》里創(chuàng)建的UpdateWithTransaction方法,該方法將ProductsDataTable傳遞給ProductsTableAdapter的UpdateWithTransaction方法.于是啟動(dòng)一個(gè)ADO.NET事務(wù),TableAdatper針對添加的每一個(gè)ProductsRow向數(shù)據(jù)庫發(fā)出一個(gè)INSERT命令.如果所有的添加無誤則提交事務(wù),否則對事務(wù)回滾.

  對“Add Products from Shipment”按鈕的Click處理器進(jìn)行編碼時(shí),應(yīng)該執(zhí)行一些誤差校驗(yàn),因?yàn)槲覀儧]有在添加界面里使用RequiredFieldValidators控件,某個(gè)用戶可能輸入了產(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;
 }
}

  該事件處理器開始時(shí)檢查Page.IsValid屬性返回的值是否為true。如果返回的為false,那就意味著至少有一個(gè)CompareValidators控件發(fā)現(xiàn)了無效的數(shù)據(jù).此時(shí),我們要么停止添加產(chǎn)品;要么將用戶鍵入的unit price值向ProductsRow的UnitPrice屬性賦值時(shí),以拋出一個(gè)異常告終.

  接下來創(chuàng)建一個(gè)新的ProductsDataTable instance實(shí)例(也就是products),在一個(gè)for循環(huán)里遍歷有關(guān)name和unit price的TextBox控件,并將其Text屬性讀取到局部變量productName 和 unitPrice里.如果用戶輸入了產(chǎn)品的unit price值而沒有輸入產(chǎn)品的name值,那么StatusLabel控件就會(huì)顯示消息“If you provide a unit price you must also include the name of the product”并退出事件處理器.

  如果用戶輸入了產(chǎn)品name的話,就用ProductsDataTable的NewProductsRow方法創(chuàng)建一個(gè)新的ProductsRow instance實(shí)例.對實(shí)例的ProductName屬性而言,是用相應(yīng)的TextBox來賦值;而對SupplierID 和 CategoryID屬性而言,是用添加界面頂部的相應(yīng)的DropDownList控件的SelectedValue屬性值來賦值的;如果用戶輸入里產(chǎn)品的價(jià)格,就對ProductsRow instance實(shí)例的UnitPrice屬性進(jìn)行賦值,如果用戶沒有輸入價(jià)格那么就置空,向數(shù)據(jù)庫添加數(shù)據(jù)時(shí)UnitPrice的值就為NULL值.最后,對Discontinued 和 UnitsOnOrder屬性用硬編碼的值“false”和“0”分別賦值.

  完成對ProductsRow instance實(shí)例的相關(guān)屬性賦值后,將其添加到ProductsDataTable.

  完成for循環(huán)后我們將檢查是否已經(jīng)添加了產(chǎn)品.畢竟,用戶可能沒有輸入任何的信息就點(diǎn)擊了“Add Products from Shipment”按鈕.如果在ProductsDataTable里至少存在一個(gè)產(chǎn)品,將調(diào)用ProductsBLL class類的UpdateWithTransaction方法,接下來對名為ProductsGrid的GridView控件重新進(jìn)行綁定,最新添加的產(chǎn)品就會(huì)出現(xiàn)在出現(xiàn)在展示界面里.StatusLabel將被更新以顯示一個(gè)確認(rèn)消息,然后調(diào)用ReturnToDisplayInterface,隱藏添加界面而顯示展示界面.

  如果沒有添加任何產(chǎn)品,添加界面照樣會(huì)隱藏,不過會(huì)顯示一個(gè)消息“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個(gè)產(chǎn)品后的展示界面.圖15顯示的是其中2個(gè)產(chǎn)品的界面(還有1個(gè)在前面那一頁)


圖13:當(dāng)輸入U(xiǎn)nit Price值,產(chǎn)品的Name也是必需的


圖14:添加了3個(gè)由供應(yīng)商Mayumi提供的Veggies類產(chǎn)品


圖15:新添加的產(chǎn)品可以在GridView里的最后一頁找到

  注意:本文使用的批添加邏輯將insert封裝在一個(gè)事務(wù)里.要證實(shí)的話,我們可以有意的導(dǎo)入一個(gè)數(shù)據(jù)庫級的錯(cuò)誤(database-level error).比如:對ProductsRow instance實(shí)例的 CategoryID屬性而言,我們不像上面那樣用Categories DropDownList控件的selected值來賦值,而是用i * 5對其賦值.這里的i是指介于1到5之間的循環(huán)索引值(loop indexer).因此,當(dāng)添加2個(gè)或更多的產(chǎn)品時(shí),第一個(gè)產(chǎn)品的CategoryID值(5)是有效的,而后面的產(chǎn)品的CategoryID值就無效了,因?yàn)槠渲蹬c表Categories里的CategoryID值不匹配(譯注:因?yàn)榈?個(gè)產(chǎn)品的CategoryID值為10;第3個(gè)的為15,依次類推).后果是第一個(gè)產(chǎn)品的INSERT操作成功,后面的操作失敗,因?yàn)檫`反了外鍵約束.由于我們的該批添加是原子操作,第一個(gè)INSERT會(huì)回滾,數(shù)據(jù)庫就會(huì)返回到開始批添加前的狀態(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)行加密等.

  祝編程快樂!

作者簡介

  本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創(chuàng)始人,自1998年以來一直應(yīng)用 微軟Web技術(shù)。大家可以點(diǎn)擊查看全部教程《[翻譯]Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程》,希望對大家的學(xué)習(xí)ASP.NET有所幫助。

您可能感興趣的文章:
  • C#.NET中如何批量插入大量數(shù)據(jù)到數(shù)據(jù)庫中
  • Asp.Net使用Bulk實(shí)現(xiàn)批量插入數(shù)據(jù)
  • C#/.Net 中快速批量給SQLite數(shù)據(jù)庫插入測試數(shù)據(jù)
  • asp.net新聞列表生成靜態(tài)頁之批量和單頁生成
  • 在ASP.NET 2.0中操作數(shù)據(jù)之六十二:GridView批量更新數(shù)據(jù)
  • 在ASP.NET 2.0中操作數(shù)據(jù)之三十七:DataList批量更新
  • ajax readyState的五種狀態(tài)詳解
  • AJAX(XMLHttpRequest.status)狀態(tài)碼
  • javascript學(xué)習(xí)筆記(七)Ajax和Http狀態(tài)碼
  • asp.net線程批量導(dǎo)入數(shù)據(jù)時(shí)通過ajax獲取執(zhí)行狀態(tài)

標(biāo)簽:中衛(wèi) 甘肅 海西 聊城 清遠(yuǎn) 慶陽 臨夏

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《在ASP.NET 2.0中操作數(shù)據(jù)之六十四:GridView批量添加數(shù)據(jù)》,本文關(guān)鍵詞  在,ASP.NET,2.0,中,操作,數(shù)據(jù),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《在ASP.NET 2.0中操作數(shù)據(jù)之六十四:GridView批量添加數(shù)據(jù)》相關(guān)的同類信息!
  • 本頁收集關(guān)于在ASP.NET 2.0中操作數(shù)據(jù)之六十四:GridView批量添加數(shù)據(jù)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    中文字幕乱码一区二区三区| 中文文字幕一区二区三三| 亚洲人成电影在线观看网| 亚洲精选免费视频| 日韩不卡一区二区三区| 忘忧草在线日韩www影院| 欧美三日本三级三级在线播放| 欧美成免费一区二区视频| 一级日本免费的| 国产精品久久久久一区二区国产| 99久久亚洲精品日本无码| 日韩亚洲精品在线观看| 免费国产麻豆传| 乱色588欧美| 精品黑人一区二区三区久久| 日韩在线中文字| 天堂av在线免费| 午夜视频在线免费播放| 男人亚洲天堂网| 精品国产三级a∨在线| xxxx.欧美| 一级在线视频| 国产一区二区三区在线免费| 亚洲高清国产拍精品26u| 在线人成日本视频| 国产 欧美 日韩 在线| 久久久一二三四| 中文字幕第80页| 久久精品 人人爱| 日韩理论在线观看| 最新黄色av网站| 都市激情国产精品| 久久精品国产久精国产思思| 无码人妻丰满熟妇啪啪网站| 欧美激情一区二区三区p站| 欧美在线观看网站| av直播在线观看| 黄色网址在线免费| 午夜免费福利视频| 色香蕉在线观看| 欧美午夜免费电影| 国模精品一区二区| 欧美日韩免费一区二区三区| 神马影院一区二区三区| 欧美美女性生活视频| 国产精品五区| 黄网页免费在线观看| 国产在线视频一区二区三区| 成人免费黄色网址| 欧美成人一区二区三区片免费| 国产资源在线视频| 久久不见久久见中文字幕免费| 啊啊啊一区二区| 综合区小说区图片区在线一区| 欧美美女一级片| 99久久久国产精品免费蜜臀| 国产又粗又猛又爽又黄91精品| 久久视频免费在线播放| 亚洲成a人v欧美综合天堂下载| 激情黄产视频在线免费观看| 美女尤物久久精品| 国产7777777| 在线亚洲自拍| 最近中文字幕mv免费高清在线| 91成人福利在线| 91福利国产成人精品照片| 26uuu国产电影一区二区| 亚洲国产精品人久久电影| 91在线视频九色| 一本色道88久久加勒比精品| 亚洲色图网友自拍| 成人毛片免费| 欧美日韩国产三级| 国产高清视频在线播放| 一个人看的免费视频色| 成年人免费在线视频| 女人色偷偷aa久久天堂| 992tv在线| 国产青草视频在线观看视频| 欧美成人在线直播| 国产精品国模大尺度私拍| 日韩av在线免播放器| 国产综合色产在线精品| 区一区二视频| 国产有码在线一区二区视频| 国产原厂视频在线观看| 日韩欧美天堂| 免费黄网站在线观看| 日韩一级中文字幕| 情趣网站在线观看| 精品国产一区二区三区日日嗨| 只有这里有精品| 国产女同性恋一区二区| 精品久久久久久久大神国产| 亚洲黄色免费在线观看| 日韩激情久久| 国内精品久久久久久99蜜桃| 国产精品免费看久久久无码| 直接看的黄色网址| 97久久精品| 99热这里只有精品1| 91在线中字| 免费国产黄色片| av激情在线| 在线观看一区二区三区视频| 人人爽人人爽人人片av| 日本精品一区二区在线观看| 无码精品视频一区二区三区| 久操成人av| 五月天婷婷久久| 国产人成精品| 久久久久久无码精品人妻一区二区| 欧美精品一区三区在线观看| 亚洲国产精品一区二区尤物区| 福利网在线观看| 一女被多男玩喷潮视频| 欧美国产精品中文字幕| 日本高清精品| 亚洲一卡二卡区| 第一次破处视频| 91禁在线看| 国产精品91一区二区三区| 黄色小视频在线播放| 国产午夜精品视频| 综合日韩在线| 欧美性感一类影片在线播放| 一个人看的www在线免费视频| 福利视频网站导航| 欧美精品三级| 国产精品美女久久久久av超清| 欧洲精品在线视频| 日本一区二区三级电影在线观看| 中文字幕第22页| 国产福利资源在线| 国产综合精品一区| www.18av.com| 国产后入清纯学生妹| 992tv成人国产福利在线| 涩涩av在线| 四季av一区二区凹凸精品| 久久久成人精品视频| 精品亚洲一区二区三区在线播放| 国产毛片久久久久久| 久热这里只有精品在线| 中文字幕一区av| 成人国产精品久久久久久亚洲| 在线观看精品一区二区三区| 亚洲综合欧美日韩| 亚洲动漫在线观看| 99久久亚洲| 国产精品www色诱视频| 欧美精品一区在线| 小小影院久久| japan高清日本乱xxxxx| 欧美精品欧美精品系列c| 欧美日韩爱爱视频| 亚洲资源在线看| 国产乱在线观看视频| 欧美日韩国产色| 久久精品人人做人人爽人人| 亚洲激情免费观看| 青青草原一区二区| 国产理论片在线观看| 成人精品小视频| 亚洲国产精品久久久男人的天堂| 卡一卡二国产精品| 亚洲午夜精品一区 二区 三区| 国产欧美一区二区三区国产幕精品| 国产精品视频一二三区| 亚洲永久免费精品| 91精品少妇一区二区三区蜜桃臀| 久草青青在线观看| 日韩精品一区二区三区免费观看| 久草精品在线播放| 久久97精品| 7777kkk亚洲综合欧美网站| 久久久999免费视频| 国严精品久久久久久亚洲影视| 丝袜久久网站| 中文字幕亚洲激情| 久久综合给合久久狠狠狠97色69| 91精品国产综合久久久蜜臀粉嫩| www黄色av| 成人av.网址在线网站| 超碰91人人草人人干| 乳色吐息在线观看| www国产成人免费观看视频 深夜成人网| 91视频国产高清| 日韩另类在线| 成全电影播放在线观看国语| 一区二区三区视频免费在线观看| 美女视频黄免费的亚洲男人天堂| 国产一区二区三区日韩欧美| 345成人影院| 日韩av不卡电影| 成人av电影在线播放| 99国精产品一二二线| 一个人看的www视频免费观看| 久久精品国产清高在天天线| 自拍欧美一区| 女人十八岁毛片| 国产一区二区毛片| 456国产精品| 亚洲色欲色欲www在线观看| 成人黄色国产精品网站大全在线免费观看| 日本精品600av| 国模雨婷捆绑高清在线| 亚洲国产美女久久久久| 亚洲国产成人私人影院| 成人免费直播在线| 欧美视频在线一区| 国产麻豆欧美日韩一区| 中文字幕无线码一区| jizzjizz日本护士免费| 欧美连裤袜在线视频| 在线成人黄色| 牛夜精品久久久久久久99黑人| 国产伦精品一区二区三区视频网站| 91人人爽人人爽人人精88v| 亚洲最大福利视频| 久久精品国产亚洲| 九九九热精品免费视频观看网站| 黄色大片网站在线观看| 日韩电影免费| 欧美 日韩 国产精品| 每日在线更新av| 日日摸夜夜夜夜夜添| 国产午夜久久av| av中文在线播放| 你懂的亚洲视频| 波多野结衣综合网| 国产精品1区在线| 黄色综合网站| 国产成人精品免费视频大全软件| 亚洲国产成人精品久久| 精品黄色一级片| 91久久国语露脸精品国产高跟| 黄色在线免费看| 国产a久久精品一区二区三区| 黄色网页在线免费观看| 国产精品国产三级在线观看| 欧美性资源免费| 三级久久三级久久| 国产女片a归国片aa| 搞黄网站在线看| 中文字幕久精品免| 亚洲精品videossex少妇| 欧美91看片特黄aaaa| 欧美不卡高清| 国产无码精品一区二区| 噜噜噜天天躁狠狠躁夜夜精品| 国产黄色片在线| jizzjizzjizz中国免费| 久久精品亚洲牛牛影视| 欧美综合欧美视频| 精品免费国产一区二区| 国产午夜视频在线| 色悠悠久久综合| jizzjizz亚洲中国少妇| 精品久久久久久久久久久下田| 69xxx免费视频| 男生操女生视频在线观看| av动漫免费观看| 偷拍视频一区二区| 91www成人久久| 深夜视频在线观看| 欧美日韩国产色综合一二三四| www.av99| 精品国产一区二区亚洲人成毛片| 99精品全国免费观看视频软件| 日日狠狠久久偷偷综合色| 亚洲大胆美女视频| 国内精品伊人久久久| 成人一区二区三区视频在线观看| 欧美高清在线视频观看不卡| 白白色 亚洲乱淫| 日韩特级毛片| 88久久精品无码一区二区毛片| 一级黄色录像大片| 在线观看91| 俄罗斯一级**毛片在线播放| 欧美有码视频| 欧美激情一区二区三区久久久| 日韩精品免费一线在线观看| 国严精品久久久久久亚洲影视| 精品国产99久久久久久| 一区二区三区无码高清视频| 中文资源在线官网| 奇米777在线视频| 波多野结衣av在线| 国产精品日韩在线一区| 老熟妇高潮一区二区高清视频| 77777_亚洲午夜久久多人| 久久精品国内一区二区三区水蜜桃| 亚洲国产精品一区在线观看不卡| 欧美激情第3页| 欧美日韩你懂得| 亚洲精品美女在线观看| 亚洲区一区二区三| 中文字幕精品一区二| 亚瑟一区二区三区四区| 欧美1区2区| 亚洲天堂网在线视频| 老司机成人在线| 久久久成人精品| 精品偷拍一区二区三区在线看| 粗暴91大变态调教| 日韩精品免费视频人成| 97碰碰视频| 精品国产午夜福利| 中文字幕在线观看网址| 亚洲女人小视频在线观看| 久久婷五月综合| 久久免费视频色| 妖精视频一区二区三区| 国产精品高潮久久久久无| 国产精品久久久久久久久毛片| 日韩你懂的在线观看| 久久精品无码一区二区三区毛片| 国产亚洲精品va在线观看| 精品视频在线观看免费| 色又黄又爽网站www久久| 狠狠色综合色区| 欧美日韩视频第一区| av色影在线看免费| 成年人三级视频| 亚洲精品国精品久久99热| 欧美大片第1页|