チュートリアル : LinqDataSource コントロールと GridView コントロールを使用したデータのサブセットの選択およびフィルタ処理
更新 : 2007 年 11 月
このチュートリアルでは、LinqDataSource コントロールを使用して、複数のデータベース テーブルから値を取得してデータ セットを作成する方法を説明します。ここでは、LinqDataSource コントロールを使用して、テーブルからデータのサブセットを選択し、選択した値から新しい値を計算し、関連するテーブルから値を取得します。また、返されるレコードのフィルタ処理も行います。その後で、GridView コントロールを使用して、新しい値のセットを表示します。
このチュートリアルでは、主に AdventureWorks サンプル データベースの Product テーブルから値を選択して、データにアクセスする方法を示します。Product テーブルには、他のテーブルへの外部キーである列が含まれており、これらの関連テーブルからデータを取得します。
さらに、オブジェクト リレーショナル デザイナ を使用して、値を含むデータベース テーブルを表すクラスを作成します。LinqDataSource コントロールはこの生成されたクラスと対話して、データを取得および更新します。
前提条件
このチュートリアルの手順を実行するための要件は次のとおりです。
Visual Studio 2008 または Visual Web Developer Express Edition。
ASP.NET Web サイト。
SQL Server Express Edition。SQL Server がインストールされている場合、SQL Server も使用できますが、いくつかの手順を微調整する必要があります。
AdventureWorks データベースがコンピュータにインストールされていること。AdventureWorks データベースをダウンロードするには、「SQL Server 2005 Samples and Sample Databases」を参照してください。
AdventureWorks データベースに接続する接続文字列が Web サイトで指定されていること。
データベース エンティティを表すクラスの作成
LinqDataSource コントロールを使用してデータベースのデータを操作するには、データベース エンティティを表すクラスを作成します。このクラスは、Visual Studio 2008 のツールを使用して作成できます。
AdventureWorks データベースのテーブルを表すクラスを作成するには
Web サイトに App_Code フォルダがない場合は、ソリューション エクスプローラでプロジェクト名を右クリックし、[ASP.NET フォルダの追加] をクリックして、[App_Code] をクリックします。
App_Code フォルダを右クリックし、[新しい項目の追加] をクリックします。
[新しい項目の追加] ダイアログ ボックスが表示されます。
[Visual Studio にインストールされたテンプレート] で、[LINQ to SQL クラス] を選択し、ファイルに "AdventureWorks.dbml" という名前を付けます。次に、[追加] をクリックします。
[オブジェクト リレーショナル デザイナ] が表示されます。
サーバー エクスプローラで、Product (Production) テーブルを [オブジェクト リレーショナル デザイナ] ウィンドウへドラッグします。
Product (Production) テーブルとその列が、デザイナ ウィンドウに Product という名前のエンティティとして表されます。
ProductSubCategory テーブルと UnitMeasure テーブルをデザイナ ウィンドウへドラッグします。
これらのテーブルとその列が、デザイナ ウィンドウにエンティティとして表示されます。Product テーブルと 2 つの関連テーブルとの関係が点線で表示されます。
AdventureWorks.dbml ファイルを保存します。
ソリューション エクスプローラで、AdventureWorks.designer.cs ファイルまたは AdventureWorks.designer.vb ファイルを開きます。
このファイルには、AdventureWorksDataContext、Product、ProductSubCategory、および UnitMeasure という名前の各クラスが含まれています。Product クラスには、ProductSubcategory、UnitMeasure、および UnitMeasure1 という名前の各プロパティが含まれています。これらのプロパティは、AssociationAttribute 属性によって外部キーとしてマークされています。これらのプロパティは、ProductSubCategory テーブルと UnitMeasure テーブルを表すオブジェクトを返します。
UnitMeasure プロパティは、SizeUnitMeasureCode 列の値の外部キー関係を表します。UnitMeasure1 プロパティは、WeightUnitMeasureCode 列の外部キーを表します。
取得する列の選択
Select プロパティに値を指定していない場合、LinqDataSource コントロールは、データベース テーブルを表すクラスのすべてのプロパティ (列) を返します。
LinqDataSource コントロールを使用してデータのサブセットを取得するには
Visual Studio で、新しい ASP.NET Web ページを作成し、ソース ビューに切り替えます。
ツールボックスの [データ] タブから、LinqDataSource コントロールをドラッグして Web ページ上の form 要素内にドロップします。
ID プロパティは "LinqDataSource1" のままにします。
ContextTypeName プロパティを AdventureWorksDataContext に設定します。
AdventureWorksDataContext クラスは、AdventureWorks データベースを表すデータ コンテキスト クラスです。これには、データベース内の各テーブルを表すプロパティが含まれています。
TableName プロパティを Products に設定します。
Select プロパティを次のように設定します。
new(Name, Size, StandardCost, ListPrice, DaysToManufacture)
Select プロパティを設定すると、Products クラスから取得するプロパティを制限できます。クラスから複数のプロパティを選択する場合は、プロパティを new 演算子内に記述する必要があります。これは、LinqDataSource コントロールが、TableName プロパティで指定されたクラスのインスタンスを返さないからです。代わりに、このコントロールは、これらのプロパティだけを含む動的に作成されたクラスのインスタンスを返します。
取得するレコードのフィルタ処理
Where プロパティに値を指定していない場合、LinqDataSource コントロールは、データベース テーブルからすべてのレコードを返します。Where プロパティを設定することで、返されるレコードをフィルタ処理できます。静的な値を使用してフィルタ処理することもできます。たとえば、ListPrice > 0 と指定すると、ListPrice プロパティが 0 を超える値であるレコードだけが返されます。また、WhereParameters コレクションにパラメータを追加することにより、実行時に値を割り当てることもできます。
LinqDataSource コントロールを使用して実行時にデータをフィルタ処理するには
DropDownList コントロールを Web ページに追加し、その AutoPostBack プロパティを true に設定します。
既定の名前である "DropDownList1" をそのまま使用します。
DropDownList1 コントロールに 4 つのリスト項目を追加し、それぞれの値を 0、25、100、および 400 に設定します。
WhereParameters 要素を、LinqDataSource コントロールの開始タグと終了タグの間に追加します。
ControlParameter コントロールを WhereParameters コレクションに追加します。
ControlParameter コントロールの ControlID プロパティを DropDownList1 に設定し、Name プロパティを SelectedPrice に、Type プロパティを Int32 に設定します。
実行時に、DropDownList1 から選択された値が SelectedPrice パラメータに格納されます。
Where プロパティを ListPrice > @SelectedPrice に設定して、ListPrice の値がユーザーによって選択された値を超える値であるレコードだけが返されるようにします。
DropDownList コントロールと LinqDataSource コントロールの宣言マークアップの例を次に示します。
<asp:DropDownList AutoPostBack="true" ID="DropDownList1" runat="server"> <asp:ListItem Value="0"></asp:ListItem> <asp:ListItem Value="25"></asp:ListItem> <asp:ListItem Value="100"></asp:ListItem> <asp:ListItem Value="400"></asp:ListItem> </asp:DropDownList> <asp:LinqDataSource ContextTypeName="AdventureWorksDataContext" TableName="Products" Where="ListPrice > @SelectedPrice" Select="new(Name, Size, StandardCost, ListPrice, DaysToManufacture)" ID="LinqDataSource1" runat="server"> <WhereParameters> <asp:ControlParameter Name="SelectedPrice" DefaultValue="0" ControlID="DropDownList1" Type="Int32" /> </WhereParameters> </asp:LinqDataSource>
データを表示するコントロールの追加
これで、GridView コントロールを追加し、LinqDataSource コントロールにバインドできるようになりました。GridView コントロールを使用すると、LinqDataSource コントロールによって管理されるデータの行を表示できます。ここでは、ユーザーがデータの並べ替えやページごとの表示を実行できるようにします。
GridView コントロールにデータのサブセットを表示するには
ツールボックスの [データ] タブで、GridView コントロールをダブルクリックしてページに追加します。
GridView コントロールの DataSourceID プロパティを LinqDataSource1 に設定します。
これにより、GridView コントロールが LinqDataSource によって返されるデータにバインドされます。
AllowPaging プロパティと AllowSorting プロパティを true に設定します。
LinqDataSource コントロールで並べ替えとページングを使用するには、AutoSort プロパティと AutoPage プロパティが true に設定されている必要があります。既定では、どちらの値も true に設定されています。
AutoGenerateColumns プロパティを false に設定します。
列の順序を指定するには、LinqDataSource コントロールの Where プロパティで指定した各プロパティ (Name、Size、StandardCost、ListPrice、および DaysToManufacture) の BoundField コントロールを作成します。
GridView コントロールの宣言マークアップの例を次に示します。
<asp:GridView AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false" DataSourceID="LinqDataSource1" ID="GridView1" runat="server"> <Columns> <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" /> <asp:BoundField DataField="Size" HeaderText="Size" SortExpression="Size" /> <asp:BoundField DataField="StandardCost" HeaderText="Standard Cost" SortExpression="StandardCost" /> <asp:BoundField DataField="ListPrice" HeaderText="List Price" SortExpression="ListPrice" /> <asp:BoundField DataField="DaysToManufacture" HeaderText="Days To Manufacture" SortExpression="DaysToManufacture" /> </Columns> </asp:GridView>
ページを保存し、Ctrl キーを押しながら F5 キーを押して、ブラウザでページを表示します。
GridView コントロールに、Product テーブルの現在のレコードの列が表示されます。列見出しをクリックするとレコードを並べ替えることができ、ページ番号をクリックするとレコードをページごとに表示できます。
データ ソースの値を使用した新しい値の計算
データベース テーブルから値を選択するだけでなく、新しい値を計算することもできます。この機能は、データ ソースの値に対して計算を実行することによってのみ取得できる値を表示する場合などに使用します。これらの値の計算結果は、GridView コントロールに表示できます。
データ ソースの値を計算して新しい値を表示するには
Select プロパティの値を次のように変更します。
new(Name, Size, StandardCost, ListPrice, ListPrice - StandardCost as PriceDifference, DaysToManufacture / 5.0 as WeeksToManufacture)
追加された値 PriceDifference と WeeksToManufacture は、データベースに存在しません。これらは、データベースの値に対して計算を実行しなければ表示できません。
GridView コントロールに、PriceDifference 列および WeeksToManufacture 列の BoundField コントロールを追加し、DaysToManufacture の BoundField コントロールを削除します。
計算後の値を表示する BoundField コントロールの宣言マークアップの例を次に示します。
<asp:BoundField DataField="PriceDifference" HeaderText="Price Difference" SortExpression="Price Difference" /> <asp:BoundField DataField="WeeksToManufacture" HeaderText="Weeks To Manufacture" SortExpression="WeeksToManufacture" />
ページを保存し、Ctrl キーを押しながら F5 キーを押して、ブラウザでページを表示します。
GridView コントロールに、Product テーブルの現在のレコードと計算された値の列が表示されます。
関連テーブルからの値の選択
1 つの LinqDataSource コントロールを使用して、テーブルの値と任意の関連テーブルの値を取得できます。テーブルに他のテーブルとの外部キー関係がある場合、オブジェクト リレーショナル デザイナ によって各関連テーブルのプロパティを含むエンティティ クラスが生成されます。これらのプロパティは、関連テーブルを表すオブジェクトを返します。このオブジェクトには、関連テーブル内のすべての列を表すプロパティが含まれます。関連テーブルの値を選択するには、関連テーブルを表すクラス内のオブジェクトにアクセスします。
関連テーブルからデータを取得するには
LinqDataSource コントロールの Select プロパティを次のように設定します。
new(Name, Size, UnitMeasure.Name as SizeMeasureName, Weight, UnitMeasure1.Name as WeightMeasureName, ProductSubcategory.Name as SubCategoryName)
SizeMeasureName、WeightMeasureName、および SubCategoryName の各プロパティには、Product テーブルと外部キー関係を持つテーブルの値が格納されます。
サイズまたは重さの測定単位が設定されている製品のみを返すには、Where プロパティを次のように設定します。
WeightUnitMeasureCode != null || SizeUnitMeasureCode != null
これらの値に対するフィルタ処理では、LinqDataSource コントロールで外部キー関係をどのように管理するかが指定されています。|| 演算子は論理 OR 演算を実行します。このため、これらの外部キーのうち少なくともどちらかに値が割り当てられているレコードだけが返されます。
LinqDataSource コントロールの宣言マークアップの例を次に示します。
<asp:LinqDataSource ContextTypeName="AdventureWorksDataContext" TableName="Products" Where="WeightUnitMeasureCode != null || SizeUnitMeasureCode != null" Select="new(Name, Size, UnitMeasure.Name as SizeMeasureName, Weight, UnitMeasure1.Name as WeightMeasureName, ProductSubCategory.Name as SubCategoryName)" ID="LinqDataSource1" runat="server"> </asp:LinqDataSource>
GridView コントロールに、表示する各列の BoundField コントロールを追加します。表示する列は、Name、Size、SizeMeasureName、Weight、WeightMeasureName、および SubCategoryName です。
GridView コントロールの宣言マークアップの例を次に示します。
<asp:GridView AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false" DataSourceID="LinqDataSource1" ID="GridView1" runat="server"> <Columns> <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" /> <asp:BoundField DataField="Size" HeaderText="Size" SortExpression="Size" /> <asp:BoundField DataField="SizeMeasureName" HeaderText="Size Unit of Measurement" SortExpression="SizeMeasureName" /> <asp:BoundField DataField="Weight" HeaderText="Weight" SortExpression="Weight" /> <asp:BoundField DataField="WeightMeasureName" HeaderText="Weight Unit of Measurement" SortExpression="WeightMeasureName" /> <asp:BoundField DataField="SubCategoryName" HeaderText="Subcategory Name" SortExpression="SubCategoryName" /> </Columns> </asp:GridView>
ページを保存し、Ctrl キーを押しながら F5 キーを押して、ブラウザでページを表示します。
GridView コントロールに、Product テーブル、ProductSubCategory テーブル、および UnitMeasure テーブルの値が表示されます。これらのレコードに対しては、並べ替えやページごとの表示ができます。
次の手順
このチュートリアルでは、LinqDataSource コントロールを使用して、クエリで返される列とレコードをカスタマイズする方法を説明しました。LinqDataSource コントロールには、これ以外に次のような機能を追加できます。
更新、挿入、および削除の各操作を有効にできます。詳細については、「チュートリアル : LinqDataSource コントロールと DetailsView コントロールを使用したデータの取得、更新、挿入、および削除」を参照してください。
データをグループ化して値を集計できます (列の値の合計や平均値の算出など)。詳細については、「方法 : LinqDataSource コントロールを使用してデータをグループ化および集計する」を参照してください。
データベースのデータを取得してから、そのデータが更新または削除されるまでの間に、そのデータが変更されていないかどうか確認できます。詳細については、「チュートリアル : LinqDataSource コントロールでのタイムスタンプを使用したデータの整合性のチェック」を参照してください。