Share via


一括削除 (C#)

作成者: Scott Mitchell

PDF のダウンロード

1 回の操作で複数のデータベース レコードを削除する方法について説明します。 ユーザー インターフェイス レイヤーでは、前のチュートリアルで作成した強化された GridView を基に構築します。 データ アクセス層では、トランザクション内で複数の削除操作をラップして、すべての削除が成功するか、すべての削除がロールバックされるようにします。

はじめに

前のチュートリアルでは、完全に編集可能な GridView を使用してバッチ編集インターフェイスを作成する方法について説明しました。 ユーザーが一度に多くのレコードを一度に編集する状況では、バッチ編集インターフェイスで必要なポストバックとキーボードからマウスへのコンテキスト スイッチがはるかに少なくなり、エンド ユーザーの効率が向上します。 この手法は、ユーザーが一度に多数のレコードを削除するのが一般的なページでも同様に便利です。

オンライン メール クライアントを使用したユーザーは、最も一般的なバッチ削除インターフェイスの 1 つである、対応する [すべてのチェック済みアイテムの削除] ボタンを含むグリッド内の各行のチェック ボックス (図 1 を参照) について既に理解しています。 このチュートリアルは、Web ベースのインターフェイスと、一連のレコードを 1 つのアトミック操作として削除するメソッドの両方を作成する前のチュートリアルのすべてのハード 作業を既に行っているので、かなり短いです。 「チェック ボックスの GridView 列の追加」チュートリアルでは、チェックボックスの列を含む GridView を作成しました。また、トランザクション内のデータベース変更の折り返しに関するチュートリアルでは、トランザクションを使用して値の ProductIDList<T>削除するメソッドを BLL で作成しました。 このチュートリアルでは、以前のエクスペリエンスを基にしてマージし、作業バッチ削除の例を作成します。

各行にチェックボックスが含まれる

図 1: 各行にチェック ボックスが含まれています (フルサイズの画像を表示する場合はクリックします)

手順 1: バッチ削除インターフェイスの作成

チェック ボックスの GridView 列の追加 」チュートリアルでバッチ削除インターフェイスを既に作成しているため、最初から作成するのではなく、 に BatchDelete.aspx コピーするだけです。 まず、フォルダー内BatchDataBatchDelete.aspxページとフォルダー内のCheckBoxField.aspxページをEnhancedGridView開きます。 CheckBoxField.aspxページから [ソース] ビューに移動し、図 2 に示すようにタグ間<asp:Content>のマークアップをコピーします。

CheckBoxField.aspxの宣言型マークアップをクリップボードにコピーする

図 2: の宣言型マークアップ CheckBoxField.aspx をクリップボードにコピーする (フルサイズの画像を表示する場合はクリックします)

次に、 の [ソース] ビューに BatchDelete.aspx 移動し、クリップボードの内容をタグ内に <asp:Content> 貼り付けます。 また、 の分離コード クラス内から の分離コード クラスCheckBoxField.aspx.csBatchDelete.aspx.cs 内にコードをコピーして貼り付けます (DeleteSelectedProductsButton のClickイベント ハンドラー、メソッド、ToggleCheckStateおよび ClickUncheckAll Buttons CheckAll のイベント ハンドラー)。 このコンテンツをコピーした後、 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 します。 GridView に最初の 10 個の製品が一覧表示された GridView が表示され、各行に製品名、カテゴリ、価格がチェックボックスと共に一覧表示されます。 [すべてオン]、[すべてオフ]、[選択した製品の削除] の 3 つのボタンが必要です。 [すべて確認] ボタンをクリックするとすべてのチェック ボックスがオンになりますが、[すべてオフ] にするとすべてのチェック ボックスがオフになります。 [選択した製品の削除] をクリックすると、選択した製品の値を ProductID 一覧表示するメッセージが表示されますが、実際には製品は削除されません。

CheckBoxField.aspxからのインターフェイスが BatchDeleting.aspx に移動されました

図 3: の CheckBoxField.aspx インターフェイスが に BatchDeleting.aspx 移動されました (フルサイズの画像を表示する 場合はクリックします)

手順 2: トランザクションを使用してチェックされた製品を削除する

バッチ削除インターフェイスが に正常にコピーされた BatchDeleting.aspx場合、残っているのは、クラスの メソッドを使用して DeleteProductsWithTransaction [選択した製品の削除] ボタンによってチェックされた製品が削除されるようにコードを ProductsBLL 更新することです。 このメソッドは、トランザクション内でのデータベースの変更の折り返しに関するチュートリアルで追加され、値のProductID入力として をList<T>受け入れ、トランザクションのスコープ内で対応するProductID各メソッドを削除します。

Button のClickイベント ハンドラーはDeleteSelectedProducts現在、次foreachのループを使用して各 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 コントロールはプログラムによって参照されます。 このチェック ボックスをオンにすると、行 s ProductID がコレクションから DataKeys 取得され、 DeleteResults Label s Text プロパティが更新され、その行が削除対象として選択されたことを示すメッセージが含まれます。

上記のコードでは、クラスの Delete メソッドのProductsBLL呼び出しがコメント アウトされるため、実際にはレコードは削除されません。この削除ロジックを適用すると、コードはアトミック操作内ではなく製品を削除します。 つまり、シーケンス内の最初のいくつかの削除が成功したが、後で失敗した場合 (外部キー制約違反が原因の可能性があります)、例外がスローされますが、既に削除された製品は削除されたままになります。

アトミック性を確保するには、代わりに クラス s DeleteProductsWithTransaction メソッドを使用するProductsBLL必要があります。 このメソッドは値の ProductID リストを受け取るため、最初にグリッドからこのリストをコンパイルし、それをパラメーターとして渡す必要があります。 最初に、 型の インスタンスを List<T> 作成します int。 ループ内で、 foreach 選択した製品 ProductID の値をこの List<T>に追加する必要があります。 ループの後、これはList<T>クラスの メソッドDeleteProductsWithTransactionProductsBLL渡す必要があります。 Button のイベント ハンドラーを 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();
    }
}

更新されたコードでは、 List<T>int (productIDsToDelete) が作成され、削除する値が ProductID 設定されます。 ループの後に foreach 、少なくとも 1 つの製品が選択されている場合、 ProductsBLL クラス s DeleteProductsWithTransaction メソッドが呼び出され、このリストが渡されます。 DeleteResultsラベルも表示され、データは GridView にリバウンドされます (新しく削除されたレコードがグリッド内の行として表示されなくなります)。

図 4 は、複数の行が削除対象として選択された後の GridView を示しています。 図 5 は、[選択した製品の削除] ボタンがクリックされた直後の画面を示しています。 図 5 ProductID では、削除されたレコードの値が GridView の下のラベルに表示され、それらの行は GridView に表示されなくなります。

選択した製品が削除されます

図 4: 選択した製品は削除されます (クリックするとフルサイズの画像が表示されます)

削除された製品の ProductID 値は、GridView の下に一覧表示されます

図 5: 削除された製品 ProductID の値は GridView の下に一覧表示されます (フルサイズの画像を表示するには、ここをクリックします)

注意

メソッドのアトミック性を DeleteProductsWithTransaction テストするには、テーブルに製品のエントリを手動で Order Details 追加し、その製品を (他のユーザーと共に) 削除します。 関連付けられた注文を含む製品を削除しようとすると、外部キー制約違反が発生しますが、選択した他の製品の削除がどのようにロールバックされるかに注意してください。

まとめ

バッチ削除インターフェイスを作成するには、チェック ボックスの列とボタン Web コントロールを含む GridView を追加します。ボタン Web コントロールをクリックすると、選択したすべての行が 1 つのアトミック操作として削除されます。 このチュートリアルでは、2 つの前のチュートリアル「 チェックボックスの GridView 列の追加 」と「 トランザクション内のデータベース変更の折り返し」で行った作業を組み合わせて、このようなインターフェイスを構築しました。 最初のチュートリアルでは、チェックボックスの列を含む GridView を作成しました。後者では、値の を渡List<T>ProductIDしたときに、トランザクションのスコープ内でそれらをすべて削除するメソッドを BLL に実装しました。

次のチュートリアルでは、バッチ挿入を実行するためのインターフェイスを作成します。

プログラミングに満足!

著者について

7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジと協力しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、ヒルトン ギーゼナウとテレサ マーフィーでした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。