亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Scott Mitchell 的ASP.NET 2.0數據教程之64:批

系統 2875 0

本文英文原版與代碼下載:
http://www.asp.net/learn/dataaccess/tutorial64cs.aspx?tabid=63


導言:

在前面的教程,我們對數據訪問層進行擴展以支持數據庫事務.數據庫事務確保一系列的操作要么都成功,要么都失敗。本文我們將注意力轉到創建一個批更新數據界面.

在本文,我們將創建一個GridView控件,里面的每一行記錄都可以進行編輯(見圖1),因此我們沒有必要多添加一列來包含Edit, Update,和Cancel按鈕,而是在頁面包含2個“Update Products”按鈕,被點擊時,遍歷所有的產品并對數據庫進行更新.讓我們開始吧.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據


圖1:GridView控件里的每一行記錄都可以編輯
注意:在第37章《Performing Batch Updates》里我們用一個DataList控件創建了一個批編輯界面, 那篇文章與本文的區別之一在于本文使用GridView控件且使用了事務.


考察設置所有GridView Rows可編輯的步驟

就像在第16章《An Overview of Inserting, Updating, and Deleting》考察的那樣,GridView控件使用內置的編輯功能編輯每一行記錄。在其內部,GridView控件通過EditIndex屬性來判斷哪一行可編輯. 一旦GridView綁定到數據源之后,它就逐行檢查,看哪行的index值與EditIndex的值匹配,如果找到的話,該行就呈現為編輯界面.如果是綁定列(BoundFields),則呈現為一個TextBox,其Text值為對應的BoundField的DataField屬性的值;如果是模板列(TemplateFields),那么呈現為EditItemTemplate而不是ItemTemplate.

我們知道當某個用戶點擊某行的Edit按鈕時,頁面產生回傳,將該行的index值為GridView控件的EditIndex屬性賦值,再重新綁定數據.當點擊某行的Cancel按鈕后產生頁面回傳,在重新綁定數據以前,將EditIndex屬性設置為-1.因為,對GridView控件的rows而言,開始時Index值為0,而將EditIndex設為-1的話就變成只讀模式了.

如果只對行進行編輯,EditIndex屬性工作正常,但不支持批編輯。要對GridView實施批編輯的話,我們必須使每行都呈現為編輯界面.為此,最簡單的方法是將要編輯的列,轉換為TemplateField,然后在ItemTemplate模板里創建編輯界面.在接下來的幾步,我們將創建一個完整的可批編輯的GridView,在第一步,我們將創建一個GridView及其ObjectDataSource,并將BoundFields和CheckBoxField轉換為TemplateFields。在第二步和第三步,我們將編輯界面從ItemTemplates模板轉移到EditItemTemplates.

第一步:展示Product信息

首先,我們先創建一個顯示產品信息的GridView.打開BatchData文件夾里的頁面BatchUpdate.aspx,從工具箱拖一個GridView控件到頁面,設ID值為ProductsGrid,從其智能標簽里綁定到一個名為ProductsDataSource的ObjectDataSource,設其調用ProductsBLL class類的GetProducts方法.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖2:設置ObjectDataSourc調用ProductsBLL Class類

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖3: 使用GetProducts方法獲取產品信息

像GridView一樣,該ObjectDataSource調用的方法也只能對每行記錄起作用。為了批更新記錄,我們必須在ASP.NET頁面的后臺代碼類里多寫些代碼,批處理數據并傳遞給BLL.因此,在ObjectDataSource的UPDATE, INSERT,和DELETE標簽里選“(None)”. 點Finish完成設置.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

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

完成設置后,ObjectDataSource控件的聲明代碼看起來和下面的差不多:

<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

完成設置后,Visual Studio會向GridView控件添加BoundFields以及一個 CheckBoxField.就本文而言,我們只允許用戶查看和編輯產品的名稱、類別、價格、以及discontinued狀態.將ProductName, CategoryName, UnitPrice和 Discontinued以外的列全部刪除,并分別將頭3個列的HeaderText屬性設置為“Product”, “Category”,“Price”。最后,啟用GridView的分頁、排序功能.

此時,GridView控件含有3個BoundFields(ProductName,CategoryName,和UnitPrice)以及一個CheckBoxField (Discontinued).我們希望將這4個列轉換為TemplateFields,并將編輯界面從TemplateField的EditItemTemplate模板轉移到ItemTemplate模板.
注意:我們在第20章《Customizing the Data Modification Interface》里探討了如何創建并定制TemplateFields.我們將BoundFields和CheckBoxField轉換成TemplateFields,然后再在ItemTemplates模板里定制其編輯界面。如果有什么不清楚的,可參考前面的文章.

從GridView的智能標簽里,點“編輯列”,這將打開Fields對話框,然后選中每一列,點擊“Convert this field into a TemplateField”。

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖5:將現有的BoundFields和CheckBoxField轉換為TemplateField


現在每一列都是TemplateField,我們將把編輯界面從EditItemTemplates模板轉移到ItemTemplates模板.


第2步:創建ProductName, UnitPrice,和Discontinued列的編輯界面

創建ProductName, UnitPrice,和Discontinued這3列的編輯界面是比較簡單的,因為它們都在TemplateField的EditItemTemplate模板里定義好了的;而創建CategoryName的編輯界面比較麻煩,因為我們需要創建一個DropDownList控件來顯示可用的categories,我們將在第3步實現.


我們首先創建ProductName的編輯界面。在GridView控件的智能標簽里點“編輯模板”,再點ProductName TemplateField的EditItemTemplate項.選中其中的TextBox,將其復制、粘貼到ProductName TemplateField的ItemTemplate模板.將該TextBox的ID屬性設置為ProductName.


然后,在ItemTemplate模板里添加一個RequiredFieldValidator控件,以確保用戶輸入的產品name不為空.將其ControlToValidate屬性設置為“ProductName”;ErrorMessage屬性為“You must provide the product's name.”;Text屬性為“*”.添加完后,屏幕看起來應該像圖6那樣:

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖6:ProductName TemplateField現在包含一個TextBox控件和一個 RequiredFieldValidator控件

對UnitPrice編輯界面而言,先從EditItemTemplate模板里將TextBox拷貝到ItemTemplate模板.然后,在TextBox前面放置一個“$”符合,將其ID屬性設置為“UnitPrice”;Columns屬性設置為“8”.

然后再添加一個CompareValidator控件,確保用戶輸入的是大于或等于$0.00的貨幣值.設其ControlToValidate屬性為“UnitPrice”;ErrorMessage 屬性為“You must enter a valid currency value. Please omit any currency symbols.”;Text屬性為“*”;Type屬性為Currency;Operator屬性為GreaterThanEqual;ValueToCompare屬性為“0”.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖7:添加一個CompareValidator控件以確保用戶輸入的是非負的貨幣值


對Discontinued TemplateField而言,直接使用已經在ItemTemplate模板里定義好了的CheckBox,只需要設其ID為“Discontinued”,Enabled屬性為true.


第三步:創建CategoryName的編輯界面

CategoryName TemplateField的EditItemTemplate模板里的編輯界面里包含一個TextBox,其用來顯示CategoryName列的值,我們要將其替換為一個DropDownList控件以顯示categories.
注意:在第20章《Customizing the Data Modification Interface》里我們詳細地探討了如何用DropDownList控件來替換TextBox控件。在此我們將過程一略而過,具體創建和設置DropDownList控件的細節可參考第20章.

從工具箱里拖一個DropDownList控件到CategoryNameTemplateField的ItemTemplate模板, 設其ID為Categories.通常情況下,我們會通過其智能標簽來定義DropDownLists的數據源,來創建一個新的ObjectDataSource.然而,這將在ItemTemplate模板里新添一個ObjectDataSource,后果是每一個GridView row都會創建一個ObjectDataSource實例.因此,我們在GridView的TemplateFields外創建ObjectDataSource.結束模板編輯,從工具箱拖一個ObjectDataSource到頁面,放置在名為ProductsDataSource的ObjectDataSource控件下面。將該新O用GetCategories Method bjectDataSource命名為CategoriesDataSource,設其使用CategoriesBLL class類的GetCategories方法.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖8:設置該ObjectDataSource使用CategoriesBLL類

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖9:從GetCategories方法獲取數據


因為該ObjectDataSource僅僅是用來檢索數據,在UPDATE 和 DELETE標簽里選 “(None)”. 點Finish完成設置.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖10:在UPDATE和DELETE標簽里選“(None)”

完成設置后,CategoriesDataSource的聲明代碼看起來根下面的差不多:

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

設置好后,返回CategoryName TemplateField的ItemTemplate模板,在DropDownList的智能標簽里點“Choose Data Source”,在數據源設置向導里,在第一個下拉列表里選CategoriesDataSource;再下面的2個下拉列表里分別選CategoryName和CategoryID.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖11:將DropDownList控件綁定到CategoriesDataSource


此時,DropDownList控件雖然列出了所有的categories,但對綁定到GridViewrow里的產品而言,其并沒有自動的選擇產品對應的category.為此,我們將DropDownList的SelectedValue值設置為產品的CategoryID值。在DropDownList的智能標簽里點“Edit DataBindings”,并將SelectedValue屬性賦值為CategoryID ,如圖12:

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖12:將產品的CategoryID值綁定到DropDownList的SelectedValue屬性

還有最后一個問題,如果產品的CategoryID為空的話,對SelectedValue的數據綁定將會拋出異常. 因為DropDownList只列出了那些指定了CategoryID值的產品,但不會列出那些CategoryID值為NULL的產品.怎樣解決呢?將DropDownList的AppendDataBoundIt屬性設為rue,并向DropDownList新添加一個item,忽略其Value屬性就像下面的聲明代碼那樣:

<asp:DropDownList ID="Categories" runat="server" AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem Value="">-- Select One --</asp:ListItem>
</asp:DropDownList>


我們注意到<asp:ListItem Value=""> “-- Select One --”里,將Value屬性設置為一個空字符串.為什么要新添該item來處理值為NULL的情況?為什么要將Value屬性設置為一個空字符串呢?這些疑問可參考前面第20章《Customizing the Data Modification Interface》
注意:這里有一個關乎性能的潛在問題要提一下。因為每行記錄都包含一個DropDownList,其數據源為CategoriesDataSource.每次登錄頁面時,都會調用CategoriesBLL class類的GetCategories方法N次,這里N為GridView控件里行的數目.對GetCategories的N次調用就會導致對數據庫的N次查詢.我們可以對返回結果進行緩存以減輕對數據庫造成的影響;至于方式嘛,可以運用per-request caching策略,也可以在緩存層Caching Layer里使用SQL高速緩存依賴性(SQL caching dependency)或基于短時間緩存周期(a very short time-based expiry)的策略。對per-request caching策略的更多信息可參考文章《HttpContext.Items – a Per-Request Cache Store》( http://aspnet.4guysfromrolla.com/articles/060904-1.aspx )

第四步:完善編輯界面

在瀏覽器里查看該頁面,就像圖13所示,每行都使用ItemTemplate模板,以包含其編輯頁面。

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖13:每個GridView Row都是可編輯的

不過仍有一些問題。首先,UnitPrice值為四個小數點,為此,返回UnitPrice TemplateField的ItemTemplate模板, 在TextBox的智能標簽里點“Edit DataBindings”,然后,將Text屬性格式指定為number.

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖14:將Text格式指定為Number


然后,將Discontinued列里的checkbox控件居中(而不是居左),在GridView的智能標簽里點“編輯列”,選取左邊方框里的Discontinued,再在右邊方框里的ItemStyle里將HorizontalAlign屬性設置為Center,如圖15所示:

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據
圖15:將Discontinued列里的CheckBox居左


接下來在頁面上添加一個ValidationSummar控件,將其ShowMessageBox屬性設置為true;ShowSummary屬性設置為false. 同時再添加一個Button Web控件,用來更新用戶所做的更該。特別的,添加2個,一個在GridView控件上面,一個在下面,將它們的Text屬性設置為“Update Products”.由于我們已經在TemplateFields模板定義了編輯界面,那么EditItemTemplates模板就顯得多余了,將其刪除.

完成上述修改后,你的頁面聲明代碼看起來應該和下面的差不多:


<p>
<asp:Button ID="UpdateAllProducts1" runat="server" Text="Update Products" />
</p>
<p>
<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" AllowSorting="True">
<Columns>
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<ItemTemplate>
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Bind("ProductName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must provide the product's name."
runat="server">*</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category"
SortExpression="CategoryName">
<ItemTemplate>
<asp:DropDownList ID="Categories" runat="server"
AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName"
DataValueField="CategoryID"
SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem>-- Select One --</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price"
SortExpression="UnitPrice">
<ItemTemplate>
$<asp:TextBox ID="UnitPrice" runat="server" Columns="8"
Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="UnitPrice"
ErrorMessage="You must enter a valid currency value.
Please omit any currency symbols."
Operator="GreaterThanEqual" Type="Currency"
ValueToCompare="0">*</asp:CompareValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:CheckBox ID="Discontinued" runat="server"
Checked='<%# Bind("Discontinued") %>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
</p>
<p>
<asp:Button ID="UpdateAllProducts2" runat="server" Text="Update Products" />

<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ShowMessageBox="True" ShowSummary="False" />
</p>


當添加Button Web控件并對相關格式進行修改后,頁面如下圖所示:

Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據

圖16:頁面現在包含了2個“Update Products”按鈕


第五步:更新產品

當用戶登錄該頁面進行修改時并點擊“Update Products”按鈕時,我們需要將用戶輸入的值保存為一個ProductsDataTable instance實例;再將該實例傳遞給一個BLL method方法,進而將該實例傳遞給DAL層的UpdateWithTransaction method方法。該方法是在前面的文章里創建的,確保對批處理進行原子操作.

在BatchUpdate.aspx.cs文件里創建一個名為BatchUpdate的方法,代碼如下:

private void BatchUpdate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = productsAPI.GetProducts();

foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Find the ProductsRow instance in products that maps to gvRow
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);

Northwind.ProductsRow product = products.FindByProductID(productID);
if (product != null)
{
// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");

// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;
}
}

// Now have the BLL update the products data using a transaction
productsAPI.UpdateWithTransaction(products);
}

該方法調用BLL層的GetProducts method方法,通過一個ProductsDataTable來獲取所有的產品.然后遍歷GridView控件的Rows collection集,該Rows collection集包含了GridView里每行所對應的GridViewRow instance實例。由于GridView里每頁最多顯示了10行,所以GridView控件的Rows collection集包含的條碼最多不超過10條.

每行記錄的ProductID來源于DataKeys collection集,并從ProductsDataTable里選出對應的ProductsRow.這4個TemplateField input控件的值賦值給ProductsRow instance實例的屬性。當對ProductsDataTable更新完成后,又轉到BLL業務邏輯層的UpdateWithTransaction method方法,就像我們在前面的教程看到的一樣,該方法僅僅調用DAL數據訪問層的UpdateWithTransaction方法.

本文使用的批更新策略是:將ProductsDataTable里對應于GridView里每行記錄的所有row進行更新,不管用戶有沒有改動過產品信息.這種盲目的更改雖然執行起來沒什么問題,但將會導致database table里出現多余的記錄.在前面的第37章《Performing Batch Updates》里,我們考察里DataList控件的批更新界面,在那篇文章里我們使用餓代碼只更新那些確實被用戶改動過的記錄.如果愿意的話,你可以使用37章的方法.
注意:當通過GridView的智能標簽來綁定數據源時,Visual Studio會自動的將數據源的主鍵值指定為GridView的DataKeyNames屬性.如果你沒有通過GridView的智能標簽來綁定ObjectDataSource的話,我們需要手工設置GridView控件DataKeyNames屬性為“ProductID”, 以便通過DataKeys collection集來訪問ProductID值.

BatchUpdate方法里的代碼和BLL業務邏輯層里的UpdateProduct methods方法的代碼很相似,主要的區別在于UpdateProduct methods方法僅僅獲取一個單一的ProductRow instance實例.UpdateProducts methods方法里對ProductRow的屬性賦值的代碼與BatchUpdate方法里foreach循環里的代碼是一模一樣的.

最后,當點擊任意一個“Update Products”按鈕時,將調用BatchUpdate方法,為這2個按鈕的Click events事件創建事件處理器,在里面添加如下的代碼:

BatchUpdate();

ClientScript.RegisterStartupScript(this.GetType(), "message",
"alert('The products have been updated.');", true);


以上代碼首先調用BatchUpdate()方法;再使用ClientScript property屬性來注入JavaScript,以顯示一個messagebox,提示“The products have been updated.”

花幾分鐘測試代碼.在瀏覽器的登錄BatchUpdate.aspx頁面,編輯幾行記錄,點任意一個“Update Products”按鈕。假定輸入無誤,你會看到一個消息框顯示“The products have been updated.”為了測試原子操作,你可以任意添加一個CHECK約束,
比如不接受UnitPrice的值為“1234.56”。然后再登錄BatchUpdate.aspx頁面,編輯幾行記錄,確保設置其中的一條記錄的UnitPrice值為“1234.56”. 當點“Update Products”按鈕時,將會出錯。結果是所有的操作回滾,回到原來的值.


另一種可供選擇的BatchUpdate方法

上面我們探討的BatchUpdate方法從BLL業務邏輯層的GetProducts方法獲取所有的產品.
如果GridView沒有啟用分頁的話,一切都很完美.如果啟用了分頁了呢?比如可能總共有幾百、幾千、幾萬條產品記錄,而GridView里每頁只顯示了10條記錄。在這種情況下,該方法獲取了所有的記錄,但只更新其中的10條記錄,實在是難稱完美.

面對這種情況,可以考慮使用下面的BatchUpdateAlternate代替:

private void BatchUpdateAlternate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();

foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Create a new ProductRow instance
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);

Northwind.ProductsDataTable currentProductDataTable =
productsAPI.GetProductByProductID(productID);
if (currentProductDataTable.Rows.Count > 0)
{
Northwind.ProductsRow product = currentProductDataTable[0];

// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");

// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;

// Import the ProductRow into the products DataTable
products.ImportRow(product);
}
}

// Now have the BLL update the products data using a transaction
productsAPI.UpdateProductsWithTransaction(products);
}

該方法首先創建一個名為products的空白的ProductsDataTable,再通過BLL業務邏輯層的GetProductByProductID(productID)方法來獲取具體的產品信息.獲取的ProductsRow instance實例更新其屬性,就像BatchUpdate()做的那樣。更新完后,通過ImportRow(DataRow)method方法將row導入名為products的ProductsDataTable.

foreach循環完成后, products將包含那些對應于GridView里每行記錄的ProductsRowinstance實例,由于這些實例是添加(而不是更新)到products,如果我們盲目的傳遞給UpdateWithTransaction method方法的話,ProductsTableAdatper會將每條記錄插入數據庫.在此,我們必須聲明只對這些行進行更新(而不是添加).

為此,我們需要在業務邏輯層里添加一個名為UpdateProductsWithTransaction的方法來達到上述目的。該方法,就像下面代碼顯示的那樣,將ProductsDataTable里的每一個ProductsRow instances實例的RowState設置為Modified,然后將該ProductsDataTable傳遞給DAL數據訪問層的UpdateWithTransaction method方法.

public int UpdateProductsWithTransaction(Northwind.ProductsDataTable products)
{
// Mark each product as Modified
products.AcceptChanges();
foreach (Northwind.ProductsRow product in products)
product.SetModified();

// Update the data via a transaction
return UpdateWithTransaction(products);
}


總結:

GridView控件內置的編輯功能只能對每行進行編輯,對批編輯無能為力.就像本文探討的那樣,要創建一個批處理界面我們要多做一些工作。為此,我們需要將GridView里的列轉換為TemplateFields,并在ItemTemplates模板里定義編輯界面,另外要在頁面添加“Update All”按鈕,該按鈕與GridView彼此分開.該按鈕的Click event事件必須要確保遍歷GridView的Rows collection集、在一個ProductsDataTable里存儲改動信息,然后再傳遞給相應的BLL業務邏輯層的方法.

下一篇,我們將考察如何創建一個批刪除的界面,具體來說,每個GridView row都會包含一個checkbox。另外, 我們將用一個“Delete Selected Rows”按鈕來替換“Update All”按鈕.

祝編程快樂!


作者簡介:

Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用 微軟Web技術。Scott是個獨立的技術咨詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯系電郵為 mitchell@4guysfromrolla.com ,也可以通過他的博 http://ScottOnWriting.NET 與他聯系


Scott Mitchell 的ASP.NET 2.0數據教程之64:批更新數據


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 高清一级毛片一本到免费观看 | 亚洲最新视频在线观看 | 久久久国产99久久国产久 | 亚洲在线播放 | 午夜影院网页 | 一级黄色免费毛片 | 欧美整片在线 | 国产精品你懂的在线播放 | 精品在线一区二区三区 | 欧美一级毛片国产一级毛片 | 日日碰日日摸日日澡视频播放 | 久久在线精品视频 | 12一14周岁毛片免费网站 | 欧美午夜性春猛交 | 天天插天天操天天射 | 国产一级一国产一级毛片 | 精品国产调教最大网站女王 | 久久亚洲精品中文字幕三区 | 国产亚洲精品看片在线观看 | 国产日产欧美一区二区三区 | 久久国产欧美另类久久久 | 九九热这里只有精品6 | 成人在线不卡视频 | 欧美美女啪啪 | 国内视频一区 | 久久国产欧美日韩高清专区 | 最新中文字幕在线播放 | 99久久99久久久精品久久 | 国产97在线 | 亚洲 | 亚洲久草 | 日韩国产成人精品视频人 | 亚洲欧洲日本在线 | 日本久久久久中文字幕 | 国内高清久久久久久久久 | 深夜福利在线免费观看 | 国产亚洲欧美日韩综合综合二区 | 亚洲视频第二页 | 台湾一级毛片免费播放 | 日本在线毛片视频免费看 | 成人性视频免费网站 | 免费一级欧美片在线观免看 |