ASP.NET GridViewのホームへ戻る

GridViewの削除機能に同時実行時の処理を追加する (GridView05StepUp2.aspx)

 

GridViewからレコードを削除するとき楽観的ロックを適用するサンプルを作成します。このサンプルでは、GridViewから[削除]ボタンをクリックしたとき、他のユーザーからレコードがすでに更新/削除されていれば「同時実行エラー」が発生した旨のメッセージを表示して再試行するように促します。

 

このサンプルは、以下のノウハウを習得することができます。

 

GridViewの削除処理に楽観的ロックを適用する方法

 

 

ブラウザにGridView04.aspxGridView05StepUp2.aspxを表示したら先頭レコードを更新する

 

他のユーザーがレコード更新後に[削除]ボタンをクリックすると「同時実行エラー」になる

 

図 削除ボタンに楽観的ロックを組み込む 

 

 

 

1. 新規Webページ作成

 

ソリューションエクスプローラのプロジェクトの右クリックから[新しい項目の追加]を選択して、新規Webページ「GridView05StepUp2.aspx」を作成します。

 

 

2. コントロール作成

 

GridView05.aspxのデザイナからGridView1SqlDataSource1のオブジェクトをコピーしたら、GridView05StepUp2.aspxのデザイナに貼り付けします。デザイナにGridView1SqlDataSource1のオブジェクトが作成されます。ツールボックスの「標準」タブから[Label]をドラッグしたら、GridViewの上にドロップします。LabelIDを「lblResult」に書き換えたら、Textプロパティを削除して「EnableViewState="False"」を追加します。

 

<asp:Label ID="lblResult" runat="server" EnableViewState="False"></asp:Label>

 

 

3. 楽観的ロックの組み込み

 

GridViewの「GridViewタスク」メニューから[データソース構成]をクリックします。データソース構成ウィザードが起動されたら指示に従って処理を続行します。「Selectステートメントの構成」が表示されたら、[詳細設定]ボタンをクリックします。「SQL生成の詳細オプション」が表示されたら、「オプティミステック同時実行制御」をチェックして[OK]をクリックします。

 

Selectステートメントの構成」に戻ったら、[次へ]のボタンをクリックしてウィザードを完了させます。「選択されたデータソーススキーマを使用してGridView列フィールドとデータキーを再作成しますか?」のメッセージが表示されたら[いいえ]をクリックします。

 

4. イベントハンドラの追加

 

デザイナの右クリックから[コードの表示]を選択します。コードビューが表示されたら、「(全般)」のドロップダウンリストから[SqlDataSource1]、「(宣言)」のドロップダウンリストから[Deleted]を選択します。SqlDataSource1_Deletedのイベントハンドラが作成されたら、次のコードを追加します。

 

 

Protected Sub SqlDataSource1_Deleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs) Handles SqlDataSource1.Deleted

  If e.AffectedRows = 0 Then

    lblResult.Text = "同時実行エラーのため削除できません!<br />再試行してください."

  End If

End Sub

 

 

5. ブラウザに表示

 

VWD 2005のツールバーから[デバッグの開始]ボタンをクリックしてブラウザに表示します。ブラウザが起動されて、GridViewCustomersテーブルが表示されます。ブラウザ(IE)[ファイル]メニューから[新規作成]-[ウィンドウ]を選択して新規ウィンドウを開きます。2個のウィンドウが開いたら最初に開いたウィンドウを「ユーザー1」、2番目に開いたウィンドウを「ユーザー2」を想定します。次の手順で先頭レコードを更新して「同時実行エラー」を再現します。

 

ユーザー1:GridViewCustomersテーブルが表示されている状態。

ユーザー2:ブラウザのアドレスにGridView04.aspxを入力して表示します。

ユーザー2:GridViewの先頭行から[編集]ボタンをクリックして編集モードに切り替えます。

ユーザー2:「ファックス」列に「(03)-3973-XXXX」を入力したら、[更新]ボタンをクリックします。

ユーザー1:GridViewの先頭行から[削除]ボタンをクリックします。

ユーザー1:「同時実行エラーのため削除できませんでした! 再試行してください」が表示されます。

 

図 削除するレコードが他のユーザーから変更されていると「同時実行エラー」になる

 

 

 

◆解説

 

データソース構成ウィザードの「SQL生成の詳細オプション」から「オプティミステック同時実行制御」をチェックすると、SqlDataSourceDeleteCommandプロパティに次のようなDELETEステートメントが格納されます。WHERE句では、SELECTステートメントで指定したすべてのフィールドが変更されているか調べます。いずれかのフィールドが変更されていればDELETEステートメントは実行されません。

 

DELETE FROM [Customers]

WHERE [CustomerID] = @original_CustomerID

  AND [CompanyName] = @original_CompanyName

  AND [ContactName] = @original_ContactName

  AND [Phone] = @original_Phone

  AND [Fax] = @original_Fax

 

DELETEステートメントが実行されたかどうか調べるには、SqlDataSourceDeletedイベントハンドラを追加します。このイベントハンドラでは、SqlDataSouceStatusEventArgsAffectedRowsプロパティを調べてレコードが削除されたかチェックします。AffectedRowsに「0」が格納されているときは、レコードが削除されていないことを意味します。ここでは、AffectedRowsが「0」のとき、レコードが他のユーザーから更新されたと想定(レコードが削除された場合も含まれます)して「同時実行エラー」を表示します。

 

Protected Sub SqlDataSource1_Deleted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs) Handles SqlDataSource1.Deleted

  If e.AffectedRows = 0 Then

    lblResult.Text = "同時実行エラーのため削除できません!<br />再試行してください."

  End If

End Sub

 

Customersテーブルのファックス(Fax)のフィールドがNullのとき、[削除]ボタンをクリックすると「同時実行エラー」が表示されます。このエラーを回避するには以下のNoteを参照してください。

 

Note

列がNullのときレコードが削除されない不具合を回避するには

 

データベースのフィールドがNull値を許可する設定になっているとき、GridVeiwからレコードを削除してもレコードが削除されない不具合があります。この不具合を回避するには、SqlDataSourceDeleteCommandプロパティに格納されているDELETEステートメントのWHERE句を修正する必要があります。

 

たとえば、CustomersテーブルのFaxフィールドがNull値を許可してときは、WHERE句にNULLのチェックを追加します。

 

DELETE FROM [Customers]

WHERE [CustomerID] = @original_CustomerID

  AND [CompanyName] = @original_CompanyName

  AND [ContactName] = @original_ContactName

  AND [Phone] = @original_Phone

  AND ([Fax] IS NULL OR  [Fax] = @original_Fax)

 

 

ASP.NET GridViewのホームへ戻る