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

  完成界面后,剩下的事情是更新代码,以便当点击“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控件里.

/uploads/allimg/200612/1I1452K3_0.gif


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

/uploads/allimg/200612/1I14620C_0.gif


图5:被删除产品的ProductID值出现的GridView下面的Label控件里

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

总结:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjwydy.html