LINQ と同時実効性制御 その2

前回は LINQ to SQL の同時実効性制御がどのように行われているか少し触れたと思います。
今回は LINQ DataSource を使用した場合にコンフリクトをどうやって検知するかについて考えます。

今回使用するデーブルの定義はこんな感じ

制約名前
PUserIDChar(8)
 UserNamenvarchar(128)
 Updatedtimestamp

上記テーブルを こみゅぷらすDataContext として DBML ファイルを定義します。
次に Form に DataGrid を追加して、DataContext.User を DataSource に割り当てます。
定義はこんな感じ


<asp:GridView ID="GridView1" runat="server"
DataSourceID="LinqDataSource1"
DataKeyNames="UserID">
<Columns>
<asp:commandfield ShowEditButton="True"></asp:commandfield>
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="こみゅぷらすDataContext"
TableName="User"
EnableUpdate="True">
</asp:LinqDataSource>

これで更新は出来るのですが、更新中に他のユーザが同じデータを変更したことを検知出来ません。
timestamp型 の updated を DataKeyNames に追加することで変更を検知させます。
timestamp型 の値は誰かが行を更新することで変化するので更新時に行を確定できずに更新が失敗します。
このあたりは ObjectDataSource や SqlDataSource と同じ仕組みですね。

プログラム側では LinqDataSource の Updated イベントを補足し LinqDataSourceStatusEventArgs の Exception の値を調べる事で、更新の結果を調べることが出来ます。
たとえばこんな感じですね。


Protected Sub LinqDataSource1_Updated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.LinqDataSourceStatusEventArgs) Handles LinqDataSource1.Updated

 If e.Exception IsNot Nothing Then
   If TypeOf e.Exception Is System.Data.Linq.ChangeConflictException Then
     Label1.Text = "コンフリクトが発生しました。"
     e.ExceptionHandled = True
   End If
 End If
End Sub

次回は多階層での更新についてみていきます。