チュートリアル : LinqDataSource コントロールでのタイムスタンプを使用したデータの整合性のチェック
更新 : 2007 年 11 月
このチュートリアルでは、LinqDataSource コントロールを使用したデータの更新時に、タイムスタンプを使用してデータの競合をチェックする方法について説明します。LinqDataSource コントロールは、Web ページ内にタイムスタンプ値を保存します。ユーザーがデータを更新または削除すると、LinqDataSource コントロールは、このタイムスタンプ値とデータベース内の現在のタイムスタンプ値を比較します。タイムスタンプ列の値が更新されていることを検出すると、LinqDataSource コントロールはレコードの更新または削除を実行しません。このような場合は、レコードが他のプロセスによって変更されているからです。代わりに、LinqDataSource コントロールは、レコードが変更されていることを示す例外を発生させます。
タイムスタンプ列は、レコードが変更されるたびに SQL Server によって自動的に更新されます。詳細については、「timestamp (Transact-SQL)」を参照してください。エンティティ クラスでは、IsVersion プロパティを true に設定することでタイムスタンプ列が指定されます。
タイムスタンプ列を使用しない場合、LinqDataSource コントロールは、Web ページに値を格納することによってデータ操作の同時実行をチェックします。同時実行チェックに使用する値は、テーブルの主キーとして使用されている列、または ColumnAttribute 属性の UpdateCheck プロパティが UpdateCheck.Always または UpdateCheck.WhenUpdated に設定されている列で構成されます。LINQ to SQL は、データを更新または削除する前に、これらの値をデータベースと比較します。この方法では、データ レコードに多くの列が含まれている場合や、列の値が大きい場合に、Web ページのサイズが大きくなる可能性があります。また、ページ上で公開しないデータがレコードに含まれている場合は、セキュリティ上のリスクが発生する可能性もあります。
ここでは、オブジェクト リレーショナル デザイナを使用して、データベース テーブルを表すクラスを作成します。LinqDataSource コントロールはこの生成されたクラスと対話して、データを取得、更新、挿入、および削除します。
前提条件
この手順を各自の開発環境で実行するには、以下が必要です。
Visual Web Developer Express Edition または Visual Studio 2008。
使用するコンピュータに SQL Server Express Edition がインストールされていること。SQL Server がインストールされている場合、代わりに使用することもできますが、いくつかの手順を微調整する必要があります。
ASP.NET Web サイト。
データベース テーブルの作成
このチュートリアルの手順を実行するには、タイムスタンプ列を含むデータベース テーブルを用意する必要があります。そのようなテーブルがない場合は、次の手順を実行してテーブルを作成します。既存のテーブルを使用する場合、手順の一部に使用するデータベースと完全に一致しない部分があります。ただし、チュートリアルで説明する概念は同じになります。
タイムスタンプ列を含むデータベース テーブルを作成するには
Web サイトに App_Data フォルダがない場合は、ソリューション エクスプローラでプロジェクトを右クリックし、[ASP.NET フォルダの追加] をクリックして、[App_Data] をクリックします。
App_Data フォルダを右クリックし、[新しい項目の追加] をクリックします。
[インストールされているテンプレート] で、[SQL データベース] を選択し、ファイル名を Reviews.mdf に変更して [追加] をクリックします。
サーバー エクスプローラで、Reviews.mdf ノードを開き、テーブル フォルダを右クリックします。
[新しいテーブルの追加] をクリックします。
テーブルに次の列を作成します。
列名
データ型
プロパティ
BookID
int
IsIdentity = Yes
null 以外
主キー
Title
nvarchar(50)
Author
nvarchar(50)
RecommendToBookGroup
bit
null 以外
Review
nvarchar(1000)
[Timestamp]
timestamp
null 以外
作成したテーブルを BookReviews という名前で保存します。
サンプル データを使用して BookReviews テーブルにレコードを追加します。
サーバー エクスプローラで、BookReviews テーブルを右クリックし、[テーブル データの表示] をクリックします。BookID や Timestamp の値はデータベースによって生成されるため、値を指定する必要はありません。
データベース エンティティを表すクラスの作成
LinqDataSource コントロールを操作するには、データベース エンティティを表すクラスを使用します。Visual Web Developer Express Edition または Visual Studio 2008 のツールを使用して、これらのクラスを作成できます。
BookReviews テーブルのクラスを作成するには
Web サイトに App_Code フォルダがない場合は、ソリューション エクスプローラでプロジェクトを右クリックし、[ASP.NET フォルダの追加] をクリックして、[App_Code] をクリックします。
App_Code フォルダを右クリックし、[新しい項目の追加] をクリックします。
[インストールされているテンプレート] で、[LINQ to SQL クラス] を選択し、ファイル名を Reviews.dbml に変更して [追加] をクリックします。
[オブジェクト リレーショナル デザイナ] ウィンドウが表示されます。
サーバー エクスプローラで、BookReviews テーブルを [オブジェクト リレーショナル デザイナ] ウィンドウにドラッグします。
BookReviews テーブルとその列が、デザイナ ウィンドウに BookReview という名前のエンティティとして表示されます。
Reviews.dbml ファイルを保存します。
ソリューション エクスプローラで、Reviews.designer.cs ファイルまたは Reviews.designer.vb ファイルを開きます。
このエンティティには、ReviewsDataContext および BookReview という名前の各クラスが含まれています。すべての列の列属性は、UpdateCheck=UpdateCheck.Never と指定されています。ただし、タイムスタンプ列の列属性は、IsVersion=true と指定されています。
Reviews.dbml ファイルを閉じます。
LinqDataSource コントロールの作成および構成
データベース テーブルと、データベース エンティティを表すクラスを用意できました。これで、ASP.NET Web ページで LinqDataSource コントロールを使用して、表示および更新するデータを管理できます。
LinqDataSource コントロールを作成して構成するには
Visual Studio で、新しい ASP.NET Web ページを作成し、ソース ビューに切り替えます。
ツールボックスの [データ] タブで、LinqDataSource コントロールをドラッグして Web ページ上の form 要素内にドロップします。
ID プロパティは "LinqDataSource1" のままにします。
ContextTypeName プロパティを ReviewsDataContext に設定します。
TableName プロパティを BookReviews に設定します。
EnableUpdate プロパティと EnableDelete プロパティを true に設定します。
LinqDataSource コントロールの宣言コードの例を次に示します。
<asp:LinqDataSource ContextTypeName="ReviewsDataContext" TableName="BookReviews" EnableUpdate="true" EnableDelete="true" ID="LinqDataSource1" runat="server"> </asp:LinqDataSource>
データを表示および更新するコントロールの追加
これで、DetailsView コントロールを追加し、LinqDataSource コントロールにバインドできるようになりました。DetailsView コントロールを使用すると、LinqDataSource コントロールによって管理されるデータを表示および更新できます。
DetailsView コントロールを LinqDataSource コントロールのデータにバインドするには
ツールボックスの [データ] タブで、DetailsView コントロールをダブルクリックしてページに追加します。
ID プロパティは DetailsView1 のままにします。
DataSourceID プロパティを LinqDataSource1 に設定します。
コントロールの DataKeyNames プロパティを BookID に設定します。
DetailsView コントロールを使用してデータを更新または削除するには、DataKeyNames プロパティを設定する必要があります。
AllowPaging プロパティを true に設定します。
AutoGenerateEditButton プロパティと AutoGenerateDeleteButton プロパティを true に設定します。
宣言マークアップの例を次に示します。
<asp:DetailsView DataSourceID="LinqDataSource1" DataKeyNames="BookID" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" AllowPaging="true" ID="DetailsView1" runat="server"> </asp:DetailsView>
BookReviews データベースの BookID 列と Timestamp 列は、データベースによって自動的に設定されます。ユーザーはこれらの値を変更できません。
変更内容を保存します。
Ctrl キーを押しながら F5 キーを押してブラウザでページを表示します。
DetailsView コントロールに、BookReviews テーブルの現在のレコードの列が表示されます。
ブラウザを閉じます。
データの競合のチェック
データが変更されているときにタイムスタンプ列によって更新が阻止されるしくみを確認するには、テストを行います。テストでは、Web ページで更新するレコードを選択する一方で、同じレコードを Web ページ以外の場所から変更します。Web ページから更新内容を送信すると、LinqDataSource コントロールによって更新がブロックされます。
データの整合性をテストするには
Ctrl キーを押しながら F5 キーを押してブラウザでページを表示します。
レコードを選択して [編集] リンクをクリックします。レコードの更新はまだ行いません。
サーバー エクスプローラで、BookReviews テーブルを右クリックし、[テーブル データの表示] をクリックします。
Web ブラウザで開いたレコードと同じレコードの値を変更します。
ウィンドウを閉じて変更内容をデータベースに書き込みます。
変更内容が保存されると、そのレコードのタイムスタンプ列が SQL Server によって自動的に更新されます。
Web ブラウザで、更新するレコードの値を変更します。
[更新] リンクをクリックします。
行が変更されていることを示すエラー メッセージが表示されます。これは、ページ内に保存されているタイムスタンプが、データベース内のレコードのタイムスタンプと一致しないためです。
このエラーが表示されたときに操作を実行するには、Updating イベントのハンドラを作成します。
次の手順
このチュートリアルでは、LinqDataSource コントロールの使用時にデータの整合性チェックを最適化する方法を説明しました。次の方法を使用すると、LinqDataSource コントロールの機能をさらに活用できます。
データが変更されている場合に発生する例外を処理するイベント ハンドラを作成します。詳細については、Updating イベントおよび Deleting イベントのトピックを参照してください。
返されるレコードをフィルタ処理します。Select プロパティに値を指定していない場合、LinqDataSource コントロールは、データベース テーブルに含まれるすべての列を取得します。DetailsView コントロールに一部の列のみを表示する場合は、列のサブセットを選択できると便利です。詳細については、「チュートリアル : LinqDataSource コントロールと GridView コントロールを使用したデータのサブセットの選択およびフィルタ処理」を参照してください。
データをグループ化して値を集計します (列の値の合計や平均値の算出など)。詳細については、「方法 : LinqDataSource コントロールを使用してデータをグループ化および集計する」を参照してください。
参照
概念
LinqDataSource Web サーバー コントロールの概要