当前位置: 移动技术网 > IT编程>开发语言>.net > 在ASP.NET 2.0中操作数据之六十三:GridView实现批量删除数据

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

2017年12月12日  | 移动技术网IT编程  | 我要评论

1976烤翅加盟,伯爵与妖精第二季,战神1攻略

导言:

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

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

http://www.lhsxpumps.com/_images/10qianwan/20171212/b_1_201712121908106154.jpg
图1:每一行都包含一个checkbox

第一步:创建批删除界面

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

http://www.lhsxpumps.com/_images/10qianwan/20171212/b_1_201712121908102454.jpg
图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值,不过并不会真的删除产品.

http://www.lhsxpumps.com/_images/10qianwan/20171212/b_1_201712121908101983.jpg
图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控件里.

http://www.lhsxpumps.com/_images/10qianwan/20171212/b_1_201712121908109039.jpg
图4:选中的产品将被删除

http://www.lhsxpumps.com/_images/10qianwan/20171212/b_1_201712121908111041.jpg
图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有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网