導言:
在前面的第62章《GridView批次更新資料》裡,我們用GridView控制項裡定製了一個批編輯介面,同樣的我們也可以定製一個批添加介面.假設有這種情況,我們接受一批從Tokyo(東京)發過來的貨物:6種不同的tea 和 coffee,如果使用者在一個DetailsView控制項裡一次輸入一個產品,他將會重複的輸入很多相同的值,比如相同的種類(Beverages),相同的供應商(Tokyo Traders),相同的discontinued值(False),以及相同的order值(0).重複性的輸入這些相同的值不僅累,還很容易出錯.只需額外多做一些工作,我們就可以建立一個批添加介面。使用者只需一次行的選擇supplier 和category,輸入一系列產品的names 和unit prices,再點擊一個按鈕就可以將這些新產品添加進資料庫(如圖1所示).這些添加的產品的ProductName 和UnitPrice資料由介面上方的2個DropDownList控制項指定,Discontinued 和UnitsOnOrder的值由“硬編輯”指定,分別為false和0.
圖1:批添加介面
本教程,我們將建立一個如圖1所示的批添加介面。在前面2章的基礎上我們將把添加過程用事務封裝以保證原子操作.讓我們開始吧!
第一步:建立一個展示介面
我們將建立一個包含2個地區的單一頁面:展示地區和添加地區.我們在這一步建立的是展示地區,它包含一個用於展示產品的GridView控制項以及一個標題為“Process Product Shipment”的button按鈕.當點擊該按鈕時,展示介面將替換為一個如圖1所示的添加介面.如果點“Add Products from Shipment” 或 “Cancel”按鈕時又會返回展示頁面.添加介面將在第二步完成.
這個包含2個介面的頁面每次只能讓一個介面可見。我們將用2個Panel Web控制項作為容器包含這2個介面——一個Panel Web控制項包含一個介面.
首先開啟BatchData檔案夾裡的BatchInsert.aspx頁面,在設計器模式裡從工具箱裡拖一個Panel控制項到頁面(如圖2所示),設定其ID為DisplayInterface.當將Panel控制項拖到頁面時其Height 和 Width屬性分別為50px 和 125px.在屬性視窗裡清除這些屬性.
圖2:從工具箱裡拖一個Panel控制項到頁面
然後拖一個Button 和 GridView控制項到Panel控制項裡。設Button的ID為ProcessShipment ,Text屬性為“Process Product Shipment”. 設GridView的ID為ProductsGrid,從其智能標籤裡將其綁定到一個名為ProductsDataSource的ObjectDataSource.設定該ObjectDataSource調用ProductsBLL class類的GetProducts方法.由於該GridView控制項只用來展示資料,從UPDATE, INSERT, DELETE標籤裡選“(None)”. 點Finish完成設定
圖3:調用ProductsBLL Class類的GetProducts方法來顯示資料
圖4:在UPDATE, INSERT, DELETE標籤裡選“(None)”
完成ObjectDataSource設定後,Visual Studio會自動地添加一些BoundFields以及一個CheckBoxField。只保留ProductName, CategoryName, SupplierName, UnitPrice, 以及Discontinued這幾列.你可以再做一些外觀的改進.我將UnitPrice列定製為貨幣值,重新對列進行了排序,再對一些列的HeaderText值進行了修改.再在GridView的智能標籤裡啟用了“分頁”和“排序”功能.完成上述工作後,頁面的聲明代碼看起來應該和下面的差不多:
<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控制項的聲明代碼出現在<asp:Panel>標籤內部,因為這些控制項置於名為DisplayInterface的Panel控制項裡面,我們可以將Panel控制項的Visible 屬性設定為false來隱藏這些控制項.我們將在第三步看到,當點擊一個按鈕時,通過編程的方式改變Panel控制項的Visible屬性以顯示添加介面.
花點時間在瀏覽器裡登入該頁面.如圖5所示,你將看到一個顯示為“Process Product Shipment”的button按鈕,其下的GridView控制項每次列出10個產品.
圖5:GridView列出了產品並啟用排序和分頁功能
第二步:建立添加介面
建立完展示介面後,我們將建立添加介面。在本教程,我們的添加介面允許使用者同時添加5個產品,且這5個產品的category 和 supplier是一樣的,而names 和 nit price值不同.在ID為DisplayInterface的Panel控制項下面,從工具箱裡拖一個Panel控制項到頁面,設定其ID為InsertingInterface,Visible屬性為false,並清除其Height 和 Width屬性值。我們將在第三步添加代碼將其Visible屬性改為true.
接下來我們將建立如圖1所示的添加介面。該介面本來可以通過一些HTML技術來建立的,不過在這裡我們將使用一個很簡單的4列7行的table表.
注意:雖然在設計器模式裡可以使用工具箱的工具來添加<table> elements元素,不過那樣會自動添加一些我們不需要的style屬性設定.因此,我更偏向於在源視圖模式裡添加HTML <table> elements元素. 當寫好類<table>聲明代碼後,我喜歡立即切換到設計器模式,再添加Web控制項並設定其屬性。當心中有數,已經想好了要建立幾行幾列的時候,我傾向於使用靜態HTML(static HTML)而不是Table Web控制項,原因是如果使用Table Web控制項的話,我們必須通過FindControl("controlID")的方式來訪問放置在裡面的的Web控制項.不過話又說回來,如果是要建立一個動態變化的表(dynamically-sized tables)的話——比如該表的行和列都綁定到資料庫或者基於使用者自訂的標準格式,我還是要使用Table Web控制項,原因很簡單,我們可以通過編程來建立該Table Web控制項.
在ID為InsertingInterface的Panel控制項的<asp:Panel>標籤裡輸入如下的聲明代碼:
<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設定:放置名為supplier 和category的DropDownLists控制項的“頭頂行”對應的是BatchInsertHeaderRow;放置“Add Products from Shipment” 和“Cancel”按鈕的“底部行”對應的是BatchInsertFooterRow;那些包含product和unit price的TextBox控制項的行交替的運用BatchInsertRow和BatchInsertAlternatingRow.我已經在Styles.css檔案裡建立裡相應的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;}
輸入這些代碼後,切換到設計檢視,該<table>看起來是一個4列7行的表,如圖6所示:
圖6:添加介面為一個4列7行的表
現在我們在添加介面裡添加Web控制項.從工具箱拖2個DropDownList到表的相應方格裡——一個用來顯示supplier另一個用來顯示category.
將用來顯示supplier的那個DropDownList的ID設為Suppliers,並將其綁定到一個名為SuppliersDataSource的ObjectDataSource.設定該ObjectDataSource調用SuppliersBLL class類的GetSuppliers方法.並在UPDATE標籤裡選“(None)”,點擊Finish完成設定嚮導.
圖7:設定ObjectDataSource調用SuppliersBLL Class類的GetSuppliers方法
設定該DropDownList顯示CompanyName列,而傳遞的值為SupplierID列.
圖8:顯示CompanyName列,傳遞的是SupplierID列的值
將第2個DropDownList的ID設為Categories,並將其綁定到一個名為CategoriesDataSource的ObjectDataSource.該ObjectDataSource調用CategoriesBLL class類的GetCategories方法. 在UPDATE標籤裡選“(None)”,再點Finish完成設定. 最後設定該DropDownList控制項顯示CategoryName列,傳遞CategoryID列的值.
當添加這2個DropDownList控制項並綁定到相應的ObjectDataSources後,你的螢幕看起來應該和圖9差不多:
圖9:“頭部行”包含顯示Suppliers和Categories的DropDownList控制項
我們現在需要建立收集每個產品的name和price資訊的TextBox控制項。在下面的每行對應的name和price方格裡各拖放一個TextBox控制項. 分別設定它們的ID為ProductName1, UnitPrice1,ProductName2, UnitPrice2,依次類推.
對每個price TextBoxes添加一個CompareValidator控制項,設定其ControlToValidate屬性為相應控制項的ID值.同時將Operator屬性設定為GreaterThanEqual,ValueToCompare 屬性設定為“0”, Type屬性設定為Currency.這樣一來可以保證輸入的價格為有效大於或等於0的貨幣值.同時將Text屬性設定為“*”;ErrorMessage屬性為“The price must be greater than or equal to zero. Also, please omit any currency symbols.”。
注意:我們並沒有在添加介面裡包含任何的RequiredFieldValidator控制項,即便是資料庫表Products的ProductName不允許為NULL值.舉個例子,如果使用者只想在前3行輸入產品的name和unit price,而最後2行為空白,我們就僅僅向資料庫添加了3個產品。由於ProductName是必需的,當輸入了name值後,我們只需要通過編程檢查使用者是否輸入了該產品的unit price值.我們將在第四步進行該檢查.
當使用者輸入了資料,但如果輸入值包含貨幣符號的話,CompareValidator控制項將報告無效資料.在每個unit price TextBoxe控制項前添加一個“$”符合,提示使用者輸入資料的時候忽略貨幣符號.
最後,在InsertingInterface Panel控制項裡添加一個ValidationSummary控制項,設定其ShowMessageBox屬性為true,ShowSummary屬性為false.有了這些設定後,當使用者輸入一個無效的unit price值後,在TextBox控制項旁邊將會出現一個星號,且ValidationSummary控制項將顯示一個用戶端的訊息框,顯示相應的錯誤訊息.
此時,你的螢幕看起來和圖10差不多.
圖10:添加介面現在包含顯示產品的Names和Prices的TextBox控制項
接下來我們要在底部行添加“Add Products from Shipment” 和 “Cancel”按鈕.從工具箱拖2個Button控制項到介面的底部,分別設定其ID為AddProducts和CancelButton;同時分別設其Text屬性為“Add Products from Shipment”和“Cancel”.此外,將 CancelButton按鈕的CausesValidation屬性設定為false.
最後,我們需要添加一個Label Web控制項來顯示有關這2個介面的狀態資訊.比如:當使用者成功地添加了一批產品時我們希望切換到展示介面並顯示確認訊息.當然,如果使用者輸入產品資訊時只提供了price而沒有提供name資訊,我們就需要顯示一個警告資訊,提示使用者ProductName是必需的.由於我們需要顯示與這2個介面有關的資訊,將該控制項放在這2個Panel控制項的上方.
從工具箱裡拖一個Label Web控制項到頁面頂部,設其ID為StatusLabel,清除其Text屬性,設其Visible屬性和EnableViewState屬性為false. 我們在以前的教程裡探討過,將EnableViewState屬性設為false的話,我們可以通過編程的方式改變Label控制項的屬性值,而當發生頁面回傳時其又回到預設狀態.當發生某些使用者行為(user action)時,會顯示狀態資訊,而當頁面回傳時,狀態資訊又消失了.最後設定StatusLabel的CssClass屬性為“Warning”,這是我們在Styles.css檔案裡定義的CSS class名稱.
下圖顯示的是添加並設定Label控制項後的樣子
圖11:在Panel控制項上面放置id為StatusLabel的Label控制項
第三步:在展示介面和添加介面之間切換
到此,我們已經完成了展示和添加介面,不過我們仍然有2個任務要做:
1.在展示介面和添加介面之間切換
2.將產品添加到資料庫
當前,展示介面是可見的而添加介面是隱藏的.這是因為DisplayInterface Panel控制項的Visible屬性為true(預設值), 而InsertingInterface Panel控制項的Visible屬性為false.
當點擊“Process Product Shipment”按鈕時,我們向從展示介面切換到添加介面。為此,建立該按鈕的Click事件處理器,包含以下代碼:
protected void ProcessShipment_Click(object sender, EventArgs e){ DisplayInterface.Visible = false; InsertingInterface.Visible = true;}
該代碼僅僅隱藏DisplayInterface Panel而顯示InsertingInterface Panel.
接下來,我們為添加介面裡的“Add Products from Shipment”和“Cancel” 按鈕建立事件處理器.當任何一個按鈕點擊時,我們需要切換到展示介面.建立這2個按鈕的Click事件處理器以調用ReturnToDisplayInterface方法——我們馬上就要建立該方法.
該方法除了隱藏InsertingInterface Panel並顯示DisplayInterface Panel外,還需要將Web控制項返回到其預編輯狀態(pre-editing state).即把DropDownList控制項的屬性SelectedIndex設定為0,清除TextBox控制項的Text屬性.
注意:仔細思考一下,如果在返回展示介面以前,我們沒有將這些控制項返回到預編輯狀態的話將會發生什麼事情呢?比如使用者點擊“Process Products from Shipment”按鈕,然後輸入產品資訊,再點“Add Products from Shipment”按鈕,這樣將添加產品並返回展示頁面。如果使用者又想添加另一批產品,一旦點擊“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事件處理器都僅僅簡單的調用ReturnToDisplayInterface方法,不過我們將在第四步完善“Add Products from Shipment”的Click事件,添加代碼以儲存產品.
ReturnToDisplayInterface方法一開始就把Suppliers和Categories的DropDownList控制項返回其第一項;常量firstControlID和lastControlID分別用來設定添加介面裡的標明產品名稱和單價的TextBoxe控制項的開始和結束索引值. 在一個for迴圈裡設定這些控制項的Text屬性為空白字串.最後重新設定Panels控制項的Visible屬性,以顯示展示介面而隱藏添加介面.
花點時間在瀏覽器裡測試該頁面,當首次登入時你將看到如圖5所示的畫面,點“Process Product Shipment”按鈕,頁面將回傳並切換到如圖12所示的添加介面,不管點“Add Products from Shipment”還是“Cancel”按鈕都將返回展示介面.
注意:當瀏覽添加介面時,測試一下與unit price TextBox對應的驗證控制項。如果你輸入的不是貨幣值或價格比0小,當點擊“Add Products from Shipment”按鈕時,就會彈出一個用戶端的警告訊息.
圖12:點擊Process Product Shipment” 按鈕後,將切換到添加介面.
第四步:添加產品
剩下要做的事情是在“Add Products from Shipment”按鈕的Click事件處理器裡將產品添加到資料庫.為此,我們可以建立一個ProductsDataTable,並為要插入的產品添加一個ProductsRow instance執行個體。一旦添加完ProductsRows後,我們就調用並把ProductsDataTable傳遞給ProductsBLL class類的UpdateWithTransaction方法.記得我們是在第61章《在事務裡對資料庫修改進行封裝》裡建立的UpdateWithTransaction方法,該方法將ProductsDataTable傳遞給ProductsTableAdapter的UpdateWithTransaction方法.於是啟動一個ADO.NET事務,TableAdatper針對添加的每一個ProductsRow向資料庫發出一個INSERT命令.如果所有的添加無誤則提交事務,否則對交易回復.
對“Add Products from Shipment”按鈕的Click處理器進行編碼時,應該執行一些誤差校正,因為我們沒有在添加介面裡使用RequiredFieldValidators控制項,某個使用者可能輸入了產品的price而忽視裡其name。由於產品的name是必須的,如果出現這種情況的話,我們需要提醒使用者並中斷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控制項發現了無效的資料.此時,我們要麼停止添加產品;要麼將使用者鍵入的unit price值向ProductsRow的UnitPrice屬性賦值時,以拋出一個異常告終.
接下來建立一個新的ProductsDataTable instance執行個體(也就是products),在一個for迴圈裡遍曆有關name和unit price的TextBox控制項,並將其Text屬性讀取到局部變數productName 和 unitPrice裡.如果使用者輸入了產品的unit price值而沒有輸入產品的name值,那麼StatusLabel控制項就會顯示訊息“If you provide a unit price you must also include the name of the product”並退出事件處理器.
如果使用者輸入了產品name的話,就用ProductsDataTable的NewProductsRow方法建立一個新的ProductsRow instance執行個體.對執行個體的ProductName屬性而言,是用相應的TextBox來賦值;而對SupplierID 和 CategoryID屬性而言,是用添加介面頂部的相應的DropDownList控制項的SelectedValue屬性值來賦值的;如果使用者輸入裡產品的價格,就對ProductsRow instance執行個體的UnitPrice屬性進行賦值,如果使用者沒有輸入價格那麼就置空,向資料庫添加資料時UnitPrice的值就為NULL值.最後,對Discontinued 和 UnitsOnOrder屬性用硬式編碼值“false”和“0”分別賦值.
完成對ProductsRow instance執行個體的相關屬性賦值後,將其添加到ProductsDataTable.
完成for迴圈後我們將檢查是否已經添加了產品.畢竟,使用者可能沒有輸入任何的資訊就點擊了“Add Products from Shipment”按鈕.如果在ProductsDataTable裡至少存在一個產品,將調用ProductsBLL class類的UpdateWithTransaction方法,接下來對名為ProductsGrid的GridView控制項重新進行綁定,最新添加的產品就會出現在出現在展示介面裡.StatusLabel將被更新以顯示一個確認訊息,然後調用ReturnToDisplayInterface,隱藏添加介面而顯示展示介面.
如果沒有添加任何產品,添加介面照樣會隱藏,不過會顯示一個訊息“No products were added. Please enter the product names and unit prices in the textboxes”.
圖13顯示的情況是使用者輸入了unit price值而沒有輸入相應的產品name;圖14顯示的是成功添加3個產品後的展示介面.圖15顯示的是其中2個產品的介面(還有1個在前面那一頁)
圖13:當輸入Unit Price值,產品的Name也是必需的
圖14:添加了3個由供應商Mayumi提供的Veggies類產品
圖15:新添加的產品可以在GridView裡的最後一頁找到
注意:本文使用的批添加邏輯將insert封裝在一個事務裡.要證實的話,我們可以有意的匯入一個資料庫級的錯誤(database-level error).比如:對ProductsRow instance執行個體的 CategoryID屬性而言,我們不像上面那樣用Categories DropDownList控制項的selected值來賦值,而是用i * 5對其賦值.這裡的i是指介於1到5之間的迴圈索引值(loop indexer).因此,當添加2個或更多的產品時,第一個產品的CategoryID值(5)是有效,而後面的產品的CategoryID值就無效了,因為其值與表Categories裡的CategoryID值不匹配(譯註:因為第2個產品的CategoryID值為10;第3個的為15,依次類推).後果是第一個產品的INSERT操作成功,後面的操作失敗,因為違反了外鍵約束.由於我們的該批添加是原子操作,第一個INSERT會復原,資料庫就會返回到開始批添加前的狀態
結語:
在本文及前2章,我們建立裡對資料進行批更新、批刪除、批添加的介面.這些介面都用到了事務。該事務,我們是在第61章《在事務裡對資料庫修改進行封裝》裡在資料訪問層Data Access Layer裡添加的.在某些情況下,這些批資料處理介面可以極大的提升終端使用者的效率.
對處理批資料的考察到此為止.接下來的系列文章裡我們將考察Data Access Layer資料訪問層裡的多種更進階的情況。包括在TableAdapter的方法裡使用預存程序、在DAL裡進行串連和命令級(connection- and command-level)的設定、對連接字串進行加密等.
祝編程快樂!
作者簡介
本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用 微軟Web技術。大家可以點擊查看全部教程《[翻譯]Scott Mitchell 的ASP.NET 2.0資料教程》,希望對大家的學習ASP.NET有所協助。