您好,登錄后才能下訂單哦!
ASP.NET 2.0中怎么利用DataList實現批量更新,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
第一步: 在DataList的 ItemTemplate創建一個可編輯的用戶界面
在前面創建一個標準的item級編輯的DataList時,我們使用了兩個template:
ItemTemplate — 包含只讀的用戶界面(使用 Label 顯示每個product的 name 和price).
EditItemTemplate — 包含編輯的用戶界面(兩個TextBox ).
DataList的EditItemIndex屬性表明了哪個DataListItem使用EditItemTemplate來展示(如果有的話)。即ItemIndex的值等于DataList的EditItemIndex的DataListItem使用EditItemTemplate來展示。在一次只編輯一個item的情況下,這個模式工作的很好,但是在創建完全可編輯的DataList的時候就不適用了。
對完全可編輯的DataList來說,我們需要所有的DataListItem都以可編輯的界面來展示。最簡單的方法是在ItemTemplate里定義可編輯的界面。對修改supplier的address信息而言,可編輯界面里supplier表現為文本,address,city和country的值都用TextBox來表示。
首先打開BatchUpdate.aspx頁,添加一個DataList,將ID設為Suppliers。通過智能標簽添加一個名為SuppliersDataSource的ObjectDataSource控件。
圖2: 創建一個名為SuppliersDataSource的ObjectDataSource
使用SuppliersBLL類的GetSuppliers()方法配置ObjectDataSource(見圖3)。象前面一章那樣,我們將直接使用 BLL而不是通過ObjectDataSource來更新supplier信息。在UPDATE標簽里選擇None(見圖4)。
圖 3: 使用GetSuppliers() 方法配置ObjectDataSource
圖 4: 設置UPDATE 標簽為None
完成向導后,Visual Studio會自動生成DataList的ItemTemplate來在Label里顯示每個數據字段。我們需要修改這個template讓它提供編輯界面。ItemTemplate可以在設計器里通過DataList的智能標簽上的Edit Templates或直接寫聲明語法來自定義。
創建一個編輯界面,將supplier的name表現為文本,address,city和country表現為TextBox。完成這些后,你的聲明代碼應該和下面差不多:
<asp:DataList ID="Suppliers" runat="server" DataKeyField="SupplierID" DataSourceID="SuppliersDataSource"> <ItemTemplate> <h5><asp:Label ID="CompanyNameLabel" runat="server" Text='<%# Eval("CompanyName") %>' /></h5> <table border="0"> <tr> <td class="SupplierPropertyLabel">Address:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="Address" runat="server" Text='<%# Eval("Address") %>' /> </td> </tr> <tr> <td class="SupplierPropertyLabel">City:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="City" runat="server" Text='<%# Eval("City") %>' /> </td> </tr> <tr> <td class="SupplierPropertyLabel">Country:</td> <td class="SupplierPropertyValue"> <asp:TextBox ID="Country" runat="server" Text='<%# Eval("Country") %>' /> </td> </tr> </table> <br /> </ItemTemplate> </asp:DataList> <asp:ObjectDataSource ID="SuppliersDataSource" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers" TypeName="SuppliersBLL"> </asp:ObjectDataSource>
注意:和前面一章一樣,需要為DataList開啟view state。
在ItemTemplate里我使用了兩個新的CSS類,SupplierPropertyLabel和SupplierPropertyValue。它們的風格設置和ProductsPropertyLabel和ProductPropertyValue CSS類一樣,并已經加入到Styles.css中。
.ProductPropertyLabel, .SupplierPropertyLabel { font-weight: bold; text-align: right; } .ProductPropertyValue, .SupplierPropertyValue { padding-right: 35px; }
完成這些后瀏覽頁面。如圖5所示,每個DataList的item用文本顯示supplier name,用TextBox顯示address,city和country。
圖 5: DataList里的每個Supplier都可編輯
第二步: 增加“Update All” Button
圖5里顯示的信息暫時還沒提供Update按鈕。完全可編輯的DataList應該只包含一個"Update All"按鈕,而不是象前面那樣,每個item包含一個button。當點擊"Update All"時,DataList里的所有記錄將被更新。本章我們將添加兩個"Update All"button- 一個在頁的上面,一個在下面(兩個都提供相同的功能)。
先在DataList上面添加一個ID為UpdateAll1的Button。然后在DataList下面添加ID為UpdataAll2的Button。兩個Button的Text都設為"Update All"。最后為兩個Button的Click事件都創建一個event handler。我們創建一個方法,“UpdateAllSupplierAddress”,然后在事件處理中調用它。(而不是在兩個事件處理里復制相同的代碼)
protected void UpdateAll1_Click(object sender, EventArgs e) { UpdateAllSupplierAddresses(); } protected void UpdateAll2_Click(object sender, EventArgs e) { UpdateAllSupplierAddresses(); } private void UpdateAllSupplierAddresses() { // TODO: Write code to update _all_ of the supplier addresses in the DataList }
圖6是添加完"Update All"button后的頁面。
圖 6: 頁面添加了兩個“Update All” Button
第三步: 更新所有的Suppliers的 Address 信息
完成了將所有的item顯示為可編輯的界面和添加了“Update All”button后,剩下的事就是寫代碼執行批量更新。我們需要便利DataList的item,調用SuppliersBLL類的UpdateSupplierAddress方法。
可以通過DataList的Items property 來訪問DataListItem集合。通過DataListItem的引用,我們可以從DataKeys集合里獲取相關的SuppliserID,并引用ItemTemplate里的TextBox,見下面的代碼:
private void UpdateAllSupplierAddresses() { // Create an instance of the SuppliersBLL class SuppliersBLL suppliersAPI = new SuppliersBLL(); // Iterate through the DataList's items foreach (DataListItem item in Suppliers.Items) { // Get the supplierID from the DataKeys collection int supplierID = Convert.ToInt32(Suppliers.DataKeys[item.ItemIndex]); // Read in the user-entered values TextBox address = (TextBox)item.FindControl("Address"); TextBox city = (TextBox)item.FindControl("City"); TextBox country = (TextBox)item.FindControl("Country"); string addressValue = null, cityValue = null, countryValue = null; if (address.Text.Trim().Length > 0) addressValue = address.Text.Trim(); if (city.Text.Trim().Length > 0) cityValue = city.Text.Trim(); if (country.Text.Trim().Length > 0) countryValue = country.Text.Trim(); // Call the SuppliersBLL class's UpdateSupplierAddress method suppliersAPI.UpdateSupplierAddress (supplierID, addressValue, cityValue, countryValue); } }
當用戶點擊一個"Update All"button時,每個Supplier DataList里的DataListItem都執行UpdateAllSupplierAddress方法,并調用SuppliersBLL類的UpdateSupplierAddress方法,將相關的值傳過去。如果address,city或country里不輸入值,UpdateSupplierAddress會接收一個空值(不是空字符串),而相關的字段的結果會是一個database NULL。
注意:你可以添加一個顯示的狀態Label,當批量更新完成后通過它來提供一些確認信息。只更新 Addresses被修改過的記錄
本章使用的批量更新法則為每個DataList里的supplier調用UpdateSupplierAddress方法,無論address信息是否被修改過。雖然這種盲目的更新一般情況下不會有什么性能問題,但是如果你有做數據庫表的審計,那樣將會導致很多多余的記錄。每次用戶點擊"Update All"button后,不管用戶是否有修改,系統里都會為每個supplier產生一個一條新的審計記錄。
ADO.NET的DateTable和DataAdapter類被設計用來支持批量更新那些僅僅被修改,刪除或新增的記錄。DataTable的每個row都有RowState property 來指明這個row是否是新增到DataTable或從它里面刪除,修改,或沒有改變。當DataTable剛產生時,所有的row都被標記為未修改的,修改了row的任何列后row會被標記為已修改的。
在SuppliersBLL類里我們首先將supplier的記錄讀進SuppliersDataTable里然后設置Address,City和Country列的值來更新指定的supplier的信息,見以下代碼:
public bool UpdateSupplierAddress (int supplierID, string address, string city, string country) { Northwind.SuppliersDataTable suppliers = Adapter.GetSupplierBySupplierID(supplierID); if (suppliers.Count == 0) // no matching record found, return false return false; else { Northwind.SuppliersRow supplier = suppliers[0]; if (address == null) supplier.SetAddressNull(); else supplier.Address = address; if (city == null) supplier.SetCityNull(); else supplier.City = city; if (country == null) supplier.SetCountryNull(); else supplier.Country = country; // Update the supplier Address-related information int rowsAffected = Adapter.Update(supplier); // Return true if precisely one row was updated, // otherwise false return rowsAffected == 1; } }
無論值是否有被修改,這段代碼都將傳入的address,city和country的值賦給SuppliersDataTable的SuppliersRow。這個修改將使SuppliersRow的RowState屬性被標記為已修改的。當DAL的Update方法被調用時,它發現SupplierRow已經被修改了,因此向數據庫發送UPDATE命令。
然而想象一下,我們為這個方法添加的代碼僅僅在和已經存在的值不一樣時才將傳入的address,city和country的值賦給SuppliersRow。在address,city和country沒有修改的情況下,SupplierRow的RowState仍然標記為未改變。這樣的結果是當DAL的Update方法被調用時,SuppliersRow沒有被修改,因此不會調用數據庫。使用以下的代碼代替前面盲目的賦值:
// Only assign the values to the SupplierRow's column values if they differ if (address == null && !supplier.IsAddressNull()) supplier.SetAddressNull(); else if ((address != null && supplier.IsAddressNull()) || (!supplier.IsAddressNull() && string.Compare(supplier.Address, address) != 0)) supplier.Address = address; if (city == null && !supplier.IsCityNull()) supplier.SetCityNull(); else if ((city != null && supplier.IsCityNull()) || (!supplier.IsCityNull() && string.Compare(supplier.City, city) != 0)) supplier.City = city; if (country == null && !supplier.IsCountryNull()) supplier.SetCountryNull(); else if ((country != null && supplier.IsCountryNull()) || (!supplier.IsCountryNull() && string.Compare(supplier.Country, country) != 0)) supplier.Country = country;
增加了這些代碼后,DAL的Update方法僅僅在更改過address相關的值的那些記錄里才向數據庫發送UPDATE命令。
當然我們也可以追蹤傳入的字段和數據庫數據是否有區別,如果沒有,就不需要調用DAL的Update方法。這種方法在你使用直接的數據庫命令時非常有效,因為直接的數據庫命令不會檢查SuppliersRow來決定是否需要調用數據庫。
注意:每次UpdateSupplierAddress方法被調用時,都會調用一次數據庫來獲取需要更新的記錄的信息。如果數據被修改,又要調用一次數據庫來更新數據。這個流程可以通過創建一個重載的UpdateSupplierAddress方法來優化,這個方法接受一個EmployeesDataTable ,它包含BatchUpdate.aspx頁的所有的修改。然后它會調用一次數據庫來獲取Suppliers表里的所有記錄。在結果集里僅僅是被修改過的記錄才能被更新。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。