欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据

程序员文章站 2023-12-12 15:51:52
导言:   在前面的教程,我们用gridview创建了一个批编辑界面。在用户需要一次性编辑多条记录的情况下,批编辑界面很有用。同理,当用户需要同时删除多条记录时,该技术也...

导言:

  在前面的教程,我们用gridview创建了一个批编辑界面。在用户需要一次性编辑多条记录的情况下,批编辑界面很有用。同理,当用户需要同时删除多条记录时,该技术也很有用.

  如果你使用过邮件系统的话,你应该对这种最常见的批删除界面很熟悉:界面里每一行都包含一个checkbox,此外,还有一个“delete all checked items”按钮(如图1).本教程比较短,因为我们在前面的教程已经完成大体的框架,在前面的第50章《为gridview控件添加checkbox》里我们创建了一个包含一个checkboxes列的gridview控件;而在61章《》里,我们在bll业务逻辑层里创建了一个方法,该方法使用事务来删除基于productid 的记录.在本教程,我们将整合这些内容来创建一个处理批删除的示例.

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据
图1:每一行都包含一个checkbox

第一步:创建批删除界面

  由于我们在第52章已经创建了一个批删除界面,因此我们可以简单的将其拷贝到batchdelete.aspx页面。首先,打开batchdata文件夹里的batchdelete.aspx页面,以及enhancedgridview文件夹里的checkboxfield.aspx页面。在checkboxfield.aspx页面,切换到source模式,将<asp:content>标签里的代码进行复制.

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据
图2:复制checkboxfield.aspx页面里的声明代码

  然后,切换到batchdelete.aspx页面的source模式,将代码粘贴到<asp:content>标签里.同理,将checkboxfield.aspx.cs里面的后台代码拷贝到batchdelete.aspx.cs里.(具体来说,就是将deleteselectedproducts按钮的click event事件、togglecheckstate方法、checkall 和 uncheckall按钮的click event事件)。完成拷贝后,batchdelete.aspx页面的后台代码类应该包含下面的代码:

using system;
using system.data;
using system.configuration;
using system.collections;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;

public partial class batchdata_batchdelete : system.web.ui.page
{
 protected void deleteselectedproducts_click(object sender, eventargs e)
 {
 bool atleastonerowdeleted = false;

 // iterate through the products.rows property
 foreach (gridviewrow row in products.rows)
 {
 // access the checkbox
 checkbox cb = (checkbox)row.findcontrol("productselector");
 if (cb != null && cb.checked)
 {
 // delete row! (well, not really...)
 atleastonerowdeleted = true;

 // first, get the productid for the selected row
 int productid = convert.toint32(products.datakeys[row.rowindex].value);

 // "delete" the row
 deleteresults.text += string.format
  ("this would have deleted productid {0}<br />", productid);

 //... to actually delete the product, use ...
 //productsbll productapi = new productsbll();
 //productapi.deleteproduct(productid);
 //............................................
 }
 }

 // show the label if at least one row was deleted...
 deleteresults.visible = atleastonerowdeleted;
 }

 private void togglecheckstate(bool checkstate)
 {
 // iterate through the products.rows property
 foreach (gridviewrow row in products.rows)
 {
 // access the checkbox
 checkbox cb = (checkbox)row.findcontrol("productselector");
 if (cb != null)
 cb.checked = checkstate;
 }
 }

 protected void checkall_click(object sender, eventargs e)
 {
 togglecheckstate(true);
 }

 protected void uncheckall_click(object sender, eventargs e)
 {
 togglecheckstate(false);
 }
}

  完成上述工作后,花几分钟在浏览器里测试该页面.你应该首先看到一个gridview控件列出了前10个产品,每行列出了产品的name, category,price以及一个checkbox. 同时应该有3个按钮“check all”, “uncheck all”和“delete selected products”.点“check all”按钮将会选中所有的checkboxes;而“uncheck all”按钮将释放所有的
checkboxes;点“delete selected products”的话将显示一个消息,列出选中的产品的productid值,不过并不会真的删除产品.

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据
图3:checkboxfield.aspx页面的界面搬到了batchdeleting.aspx页面

第二步:在事务里删除选中的产品

  完成界面后,剩下的事情是更新代码,以便当点击“delete selected products”按钮时,使用productsbll class类里的deleteproductswithtransaction方法来删除选中的产品.该方法是我们在第61章《》里添加的,它接受一系列的productid值,然后在一个事务里将删除对应的productid的记录.

deleteselectedproducts按钮的click事件目前使用的foreach循环如下:

// iterate through the products.rows property
foreach (gridviewrow row in products.rows)
{
 // access the checkbox
 checkbox cb = (checkbox)row.findcontrol("productselector");
 if (cb != null && cb.checked)
 {
 // delete row! (well, not really...)
 atleastonerowdeleted = true;

 // first, get the productid for the selected row
 int productid = convert.toint32(products.datakeys[row.rowindex].value);

 // "delete" the row
 deleteresults.text += string.format
 ("this would have deleted productid {0}<br />", productid);

 //... to actually delete the product, use ...
 //productsbll productapi = new productsbll();
 //productapi.deleteproduct(productid);
 //............................................
 }
}

  对每行而言,编程引用productselector checkbox控件,如果它被选中,从datakeys collection集获取该产品的productid值,然后更新deleteresults控件的text属性以显示要删除该行.

  上面的代码并不会真的删除任何的记录,因为在productsbll class类里我们只是注释出了如何使用delete方法。 不过就算实际地运用了这些删除逻辑,这些代码虽然可以删除产品但没有运用原子操作.也就是说,如果按顺序对头几个产品删除成功,如果接下来的某个产品删除失败(比如可能是违背里外键约束),那么将抛出一个异常,但是前面的删除操作并不会回滚.

  为了保证使用原子操作,我们将转为使用productsbllclass类的deleteproductswithtransaction method方法.由于该方法接受一系列的productid值,
我们首先需要编译这一系列的值,再将其作为参数传递出去.我们首先创建一个int类型的list<t>的实例,在foreach循环里我们需要将产品的productid值添加给list<t>,结束循环后,list<t>将传递给productsbll class类的deleteproductswithtransaction method方法,用下面的代码对deleteselectedproducts按钮的click事件处理器进行更新:

protected void deleteselectedproducts_click(object sender, eventargs e)
{
 // create a list to hold the productid values to delete
 system.collections.generic.list<int> productidstodelete =
 new system.collections.generic.list<int>();

 // iterate through the products.rows property
 foreach (gridviewrow row in products.rows)
 {
 // access the checkbox
 checkbox cb = (checkbox)row.findcontrol("productselector");
 if (cb != null && cb.checked)
 {
 // save the productid value for deletion
 // first, get the productid for the selected row
 int productid = convert.toint32(products.datakeys[row.rowindex].value);

 // add it to the list...
 productidstodelete.add(productid);

 // add a confirmation message
 deleteresults.text += string.format
 ("productid {0} has been deleted<br />", productid);
 }
 }

 // call the deleteproductswithtransaction method and show the label
 // if at least one row was deleted...
 if (productidstodelete.count > 0)
 {
 productsbll productapi = new productsbll();
 productapi.deleteproductswithtransaction(productidstodelete);

 deleteresults.visible = true;

 // rebind the data to the gridview
 products.databind();
 }
}

  上述代码创建了一个int类型的list<t>(也就是productidstodelete),并用productid值对其进行填充,foreach循环结束后,如果至少选中了一个产品,将调用productsbll 类的deleteproductswithtransaction method方法,并传递该list。名为deleteresults的label控件也将显示出来;数据重新绑定到gridview(自然,刚删除掉的记录将不会显示出来).

图4里,我们选择几个产品以删除;图5显示的是点击“delete selected products”按钮后的界面.注意,在label控件里显示的已经删除的产品的productid值,而这些产品已经删除掉了,并没有出现在gridview控件里.

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据
图4:选中的产品将被删除

在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据
图5:被删除产品的productid值出现的gridview下面的label控件里

  注意:为验证deleteproductswithtransaction method方法的原子操作,你可以为某个产品在order details表里手动添加一个条目,然后尝试删除该产品(当然与其它产品一起删除).这将会违背外键约束,注意对其它产品的删除操作是如何回滚的.

总结:

  创建一个批删除界面的话,我们需要创建一个包含checkboxes列的gridview控件,以及button web控件。当点击该按钮时,我们将删除多个产品当作一个单一原子操作.在本文,我们创建的界面整合了以前的2个章节的内容.

  在下一篇,我们考察如何创建一个批插入的界面

  祝编程快乐!

作者简介

  本系列教程作者 scott mitchell,著有六本asp/asp.net方面的书,是4guysfromrolla.com的创始人,自1998年以来一直应用 微软web技术。大家可以点击查看全部教程《[翻译]scott mitchell 的asp.net 2.0数据教程》,希望对大家的学习asp.net有所帮助。

上一篇:

下一篇: