■GridViewの削除機能に同時実行時の処理を追加する (GridView05StepUp2.aspx)
GridViewからレコードを削除するとき楽観的ロックを適用するサンプルを作成します。このサンプルでは、GridViewから[削除]ボタンをクリックしたとき、他のユーザーからレコードがすでに更新/削除されていれば「同時実行エラー」が発生した旨のメッセージを表示して再試行するように促します。
このサンプルは、以下のノウハウを習得することができます。
▼GridViewの削除処理に楽観的ロックを適用する方法

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

他のユーザーがレコード更新後に[削除]ボタンをクリックすると「同時実行エラー」になる
図 削除ボタンに楽観的ロックを組み込む
1. 新規Webページ作成
ソリューションエクスプローラのプロジェクトの右クリックから[新しい項目の追加]を選択して、新規Webページ「GridView05StepUp2.aspx」を作成します。
2. コントロール作成
GridView05.aspxのデザイナからGridView1とSqlDataSource1のオブジェクトをコピーしたら、GridView05StepUp2.aspxのデザイナに貼り付けします。デザイナにGridView1とSqlDataSource1のオブジェクトが作成されます。ツールボックスの「標準」タブから[Label]をドラッグしたら、GridViewの上にドロップします。LabelのIDを「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のツールバーから[デバッグの開始]ボタンをクリックしてブラウザに表示します。ブラウザが起動されて、GridViewにCustomersテーブルが表示されます。ブラウザ(IE)の[ファイル]メニューから[新規作成]-[ウィンドウ]を選択して新規ウィンドウを開きます。2個のウィンドウが開いたら最初に開いたウィンドウを「ユーザー1」、2番目に開いたウィンドウを「ユーザー2」を想定します。次の手順で先頭レコードを更新して「同時実行エラー」を再現します。
ユーザー1:GridViewにCustomersテーブルが表示されている状態。
ユーザー2:ブラウザのアドレスにGridView04.aspxを入力して表示します。
ユーザー2:GridViewの先頭行から[編集]ボタンをクリックして編集モードに切り替えます。
ユーザー2:「ファックス」列に「(03)-3973-XXXX」を入力したら、[更新]ボタンをクリックします。
ユーザー1:GridViewの先頭行から[削除]ボタンをクリックします。
ユーザー1:「同時実行エラーのため削除できませんでした! 再試行してください」が表示されます。

図 削除するレコードが他のユーザーから変更されていると「同時実行エラー」になる
◆解説
データソース構成ウィザードの「SQL生成の詳細オプション」から「オプティミステック同時実行制御」をチェックすると、SqlDataSourceのDeleteCommandプロパティに次のような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ステートメントが実行されたかどうか調べるには、SqlDataSourceのDeletedイベントハンドラを追加します。このイベントハンドラでは、SqlDataSouceStatusEventArgsのAffectedRowsプロパティを調べてレコードが削除されたかチェックします。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からレコードを削除してもレコードが削除されない不具合があります。この不具合を回避するには、SqlDataSourceのDeleteCommandプロパティに格納されている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) |