批量删除64

简介

前一篇教程 探讨了如何使用一个完全可编辑的 GridView 来创建批量编辑界面。在用户通常一次编辑多条记录的情况下,批量编辑界面需要更少的回传以及键盘到鼠标的上下文切换,从而提高了终端用户的效率。同理,对于常见的用户一次删除多条记录的页面,该技术也很有用。

使用过在线电子邮件客户端的人都对这种最常见的批量删除界面很熟悉:网格里的每一行都有一个复选框,还有一个对应的“Delete All Checked Items” 按钮(见图1 )。本教程内容很少,因为我们已在前面教程中完成了所有困难的工作:创建基于web 的界面和作为一个原子操作删除多条记录的方法。在为 GridView控件添加一列 Checkbox 控件 教程中,我们创建了一个包含复选框列的GridView ,在事务中封装数据库修改 教程中,我们在 BLL 中创建了一个方法,该方法使用事务来删除List<T> 的 ProductID 值。在本教程中,我们将借鉴并整合前面的经验来创建一个批量删除示例。

图1 : 每行都有一个复选框

步骤1 : 创建批量删除界面

由于我们在为 GridView控件添加一列 Checkbox 控件 教程中已经创建了批量删除界面 , 我们可简单地将其复制到 BatchDelete.aspx , 而不用重新创建。首先,打开 BatchData 文件夹中的 BatchDelete.aspx 页面,以及 EnhancedGridView 文件夹中的 CheckBoxField.aspx 页面。从 CheckBoxField.aspx 页面中,转至 Source 视图,并复制 <asp:Content> 标签之间的标记,如图 2 所示。

图2 : 将 CheckBoxField.aspx 的声明式标记复制到剪贴板

然后 , 进入BatchDelete.aspx 的 Source 视图 , 将剪贴板中的内容粘贴到 <asp:Content> 标签内。同理,将 CheckBoxField.aspx.cs 中代码文件类的代码复制到 BatchDelete.aspx.cs 的代码文件类中( DeleteSelectedProducts 按钮的 Click event handler 、 ToggleCheckState 方法以及 CheckAll 和 UncheckAll 按钮的 Click event handler )。复制完成后 ,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); 
    } 
}

复制完声明式标记和源代码后 , 花几分钟通过浏览器测试一下 BatchDelete.aspx 。应该看到一个列出了前 10 类产品的 GridView ,每行列出产品的名称、类别、价格和一个复选框。同时还应该有三个按钮: “Check All” 、 “Uncheck All” 和 “Delete Selected Products” 。单击 “Check All” 按钮会选中所有的复选框,而 “Uncheck All” 将取消选中所有的复选框。单击 “Delete Selected Products” 将显示一个消息,列出所选产品的 ProductID 值,但不会真的删除该产品。

图3 : 界面从 CheckBoxField.aspx 移到 BatchDeleting.aspx

步骤2 : 使用事务删除选中的产品

成功将批量删除界面复制到 BatchDeleting.aspx 后 , 剩下的事情是更新代码 , 以便 “Delete Selected Products” 按钮通过ProductsBLL 类的DeleteProductsWithTransaction 方法来删除选中的产品。这个 在事务中封装数据库修改 教程中增加的方法接受 List<T> 的 ProductID 值作为其输入值,并在事务范围内删除对应的每个 ProductID 。

DeleteSelectedProducts 按钮的Click event handler 目前使用以下For Each 循环来叠代各个 GridView 行 :

// 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 Web 控件。如果它被选中,从 DataKeys 集获取该行的ProductID ,然后更新 DeleteResults Label 的 Text 属性以包含指示选择删除该行的消息。

上面的代码不会真的删除任何记录,因为我们注释了对ProductsBLL 类的 Delete 方法的调用。不过就算实际运用了这些删除逻辑,代码虽然可以删除产品,但它不是在原子操作内进行的。也就是说,如果序列中的前几个删除成功,后面的一个删除失败(可能是因违反外键约束所致),将抛出一个异常,但那些已被删除的产品仍然会保持删除。

为保证使用原子操作,我们需要使用ProductsBLL 类的DeleteProductsWithTransaction 方法。由于该方法接受一系列的ProductID 值,我们首先要在网格中编译该列表,然后将它作为参数进行传递。首先创建一个int 类型的 List<T> 实例。在 foreach 循环里,我们需要将所选产品的ProductID 值添加到该 List<T> 。循环结束后,必须将该 List<T> 传递给 ProductsBLL 类的DeleteProductsWithTransaction 方法。使用下面的代码更新DeleteSelectedProducts 按钮的Click event handler :

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 方法,并传递该列表。也会显示DeleteResults Label ,数据重新绑定到GridView (这样,刚删除的记录就不再出现在网格中)。

图 4 显示的是选择删除的几行后的 GridView 。图 5 显示的是单击 “Delete Selected Products” 按钮后立即显示的屏幕。注意,在图 5 中,被删除记录的 ProductID 值显示在 GridView 下面的 Label 中,这些记录不再显示在 GridView 中。

图4 : 选中的产品将被删除

图5 : 在 GridView 的下面列出了被删除产品的 ProductID

注意 : 为验证 DeleteProductsWithTransaction 方法的原子操作 , 可在Order Details 表中手动添加某个产品的条目 , 然后尝试 ( 与其它产品一起 ) 删除该产品。在试图删除有相关订单的产品时,将会收到违反外键约束的信息,不过要留意其它所选产品的删除是如何回退的。

小结

创建一个批量删除界面 , 需要添加一个有复选框列的 GridView , 以及一个 Web 按钮控件 , 单击该按钮时 , 将在一个原子操作中删除所有选中的记录。在本教程中,我们创建的这样一个界面整合了前面两篇教程( 为 GridView 控件添加一列 Checkbox 控件 和 在事务里封装数据库修改 )中所做的工作。在第一篇教程中,我们创建了一个有复选框列的 GridView ,在后面一篇教程中,我们在 BLL 中实现了一个方法,该方法传递 List(Of T) 的 ProductID 值,并在事务范围内删除它们。

在下一篇教程中,我们将创建一个执行批量插入的界面。

快乐编程!

转载于:https://www.cnblogs.com/uddgm/articles/5451635.html

版权声明:本文为weixin_30780221原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30780221/article/details/98325541

智能推荐

Ubuntu 14.04 下,安装 Java8

下载Java http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 打开上述链接, , 下载 特定的 Java8 版本。笔者选择的是 jdk-8u172-linux-x64.tar.gz。 - 配置Java环境变量 将 jdk-8u172-linux-x64.tar.gz 解压至指定目...

OpenCV学习之路(五)图像的几何变换

在这一章将要学习图像的移动、旋转,仿射变换等 扩展缩放 我们如果想要改变图像的大小,我们就需要对图像进行扩展缩放,opencv提供给我们控制扩展缩放的函数: 参数解释: src:进行扩展缩放的原图片 dst:可以在此处设置缩放因子,也可手动设置尺寸 interpolation:在缩放时我们推荐使用cv2.INTER_AREA, 在扩展时我们推荐使用cv2.INTER_CUBIC(慢) 和 cv2....

2018.8.27

2018.8.27...

HTML 表单元素的基本样式

HTML 表单元素的基本样式 原创 ixygj197875 发布于2018-02-22 17:48:53 阅读数 2296 收藏 更新于2018-05-20 15:35:58 分类专栏: 揭秘 CSS 揭秘 CSS 收起 表单元素主要包括 label、input、textarea、select、datalist、******、progress、meter、output等,以及对表单元素进行分组的 ...

php输出语句

php输出语句 常见的输出语句 echo(): 可以一次输出多个值,多个值之间用逗号分隔。echo是语言结构(language construct),而并不是真正的函数,因此不能作为表达式的一部分使用。 print(): 函数print()打印一个值(它的参数),如果字符串成功显示则返回true,否则返回false。 print_r(): 可以把字符串和数字简单地打印出来,而数组则以括起来的键和值...

猜你喜欢

工厂模式

简介 常见的实例化对象模式。 用工厂方法替代new操作的一种模式。 当我们使用new操作实例化对象时,调用构造函数完成初始化。若初始化仅是进行赋值等简单的操作,写入构造函数即可。但如果初始化时需要执行一长串复杂的代码,将多个工作装入一个方法,是不妥的。 创建实例与使用实例分离。将创建实例所需的大量初始化工作从基类的构造函数中分离出去。 简单工厂模式、工厂方法模式针对的是一个产品等级结构;而抽象工厂...

B1105 Spiral Matrix (画图)

B1105 Spiral Matrix (25分) //第一次只拿了21分 矩阵的长和宽,求最大因子,从sqrt(num)开始枚举. 每次循环一次,s++,t--,d--,r++ 测试点四运行超时,是因为输入一个数字的时候,需要直接输出这个数字。//1分 测试点二运行超时,最后一个数字不必再while循环一次,直接输出即可。//3分 最后一个测试点卡了好久/(ㄒoㄒ)/~~ 螺旋矩阵...

Java基础=>String,StringBuffer与StringBuilder的区别

字符串常量池 什么是字符串常量池? JVM为了减少字符串对象的重复创建,其维护了一块特殊的内存,这段内存被称为字符串常量池(存储在方法区中)。 具体实现 当代码中出现字符串时,JVM首先会对其进行检查。 如果字符串常量池中存在相同内容的字符串对象,如果有,则不再创建,直接返回这个对象的地址返回。 如果字符串常量池中不存在相同内容的字符串对象,则创建一个新的字符串对象并放入常量池,并返回新创建的字符...

java调用其他java项目的Https接口

项目中是这样的: 用户拿出二维码展示,让机器识别二维码, 机器调用开门的后台系统接口, 然后开门的后台系统接口需要调用管理系统的接口, 管理系统需要判断能不能开门.这两个系统是互相独立的.当时使用http调用是没有问题的.当时后来要求必须用https.废话不说,直接代码: 我的项目中调用的是 HttpsUtils.Get(utlStr) 这个接口 开门系统接口如下图:   管理系统的接口...

Hadoop1.2.1全分布式模式配置

一 集群规划 主机名            IP                               安装的软件 &nbs...