このチュートリアルでは、EF デザイナーを使用して、定義クエリと対応するエンティティ型をモデルに追加する方法について説明します。 定義クエリは、データベース ビューで提供される機能と同様の機能を提供するために一般的に使用されますが、ビューはデータベースではなくモデルで定義されます。 定義クエリを使用すると、.edmx ファイルの DefiningQuery 要素で指定された SQL ステートメントを実行できます。 詳細については、SSDL 仕様の「DefiningQuery」を参照してください。
定義クエリを使用する場合は、モデルでエンティティ型を定義する必要もあります。 エンティティ型は、定義クエリによって公開されるデータを表示するために使用されます。 このエンティティ型によって表示されるデータは読み取り専用であることに注意してください。
パラメーター化されたクエリは、クエリの定義として実行できません。 ただし、データを更新するには、データをストアド プロシージャに表示するエンティティ型の挿入、更新、および削除関数をマッピングします。 詳細については、「 ストアド プロシージャを使用した挿入、更新、および削除」を参照してください。
このトピックでは、次のタスクを実行する方法について説明します。
- 定義クエリを追加する
- エンティティ型をモデルに追加する
- 定義クエリをエンティティ型にマップする
前提条件
このチュートリアルを完了するための要件を次に示します。
- 最新バージョンの Visual Studio。
- 「School」サンプル データベース。
プロジェクトを設定する
このチュートリアルでは、Visual Studio 2012 以降を使用します。
- Visual Studio を開きます。
- [ファイル] メニューの [新規作成] をポイントし、 [プロジェクト] をクリックします。
- 左側のウィンドウで、 Visual C# をクリックし、 コンソール アプリケーション テンプレートを選択します。
- プロジェクトの名前として 「DefiningQuerySample 」と入力し、[ OK] をクリックします。
School データベースに基づいてモデルを作成する
ソリューション エクスプローラーでプロジェクト名を右クリックし、[ 追加] をポイントして、[ 新しい項目] をクリックします。
左側のメニューから [データ] を選択し、[テンプレート] ペインの [ADO.NET Entity Data Model] を選択します。
ファイル名 として「DefiningQueryModel.edmx 」と入力し、[ 追加] をクリックします。
[モデルのコンテンツの選択] ダイアログ ボックスで、[データベースから生成] を選択し、[次へ] をクリックします。
[新しい接続] をクリックします。 [接続のプロパティ] ダイアログ ボックスで、サーバー名 (例: (localdb)\mssqllocaldb) を入力し、認証方法を選択します。データベース名として「School」と入力し、[OK] をクリックします。 指定したデータベース接続設定に従って、[データ接続の選択] ダイアログ ボックスが更新されます。
[データベース オブジェクトの選択] ダイアログ ボックスで、[ テーブル ] ノードをオンにします。 これにより、すべてのテーブルが School モデルに追加されます。
[完了] をクリックします。
ソリューション エクスプローラーで、 DefiningQueryModel.edmx ファイルを 右クリックし、[ファイルを 開く...] を選択します。
XML (テキスト) エディターを選択します。
次のメッセージが表示されたら、[ はい ] をクリックします。
定義クエリを追加する
この手順では、XML エディターを使用して、定義クエリとエンティティ型を .edmx ファイルの SSDL セクションに追加します。
- .edmx ファイルの SSDL セクションに EntitySet 要素を追加します (5 行目から 13 行目)。 次を指定します。
- EntitySet 要素の Name 属性と EntityType 属性のみが指定されます。
- EntityType 属性では、エンティティ型の完全修飾名が使用されます。
- 実行する SQL ステートメントは、 DefiningQuery 要素で指定されます。
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="SchoolModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityContainer Name="SchoolModelStoreContainer">
<EntitySet Name="GradeReport" EntityType="SchoolModel.Store.GradeReport">
<DefiningQuery>
SELECT CourseID, Grade, FirstName, LastName
FROM StudentGrade
JOIN
(SELECT * FROM Person WHERE EnrollmentDate IS NOT NULL) AS p
ON StudentID = p.PersonID
</DefiningQuery>
</EntitySet>
<EntitySet Name="Course" EntityType="SchoolModel.Store.Course" store:Type="Tables" Schema="dbo" />
-
EntityType 要素を .edmx の SSDL セクションに追加します。 ファイルを次に示します。 次の点に注意してください。
- Name 属性の値は、上記の EntitySet 要素の EntityType 属性の値に対応しますが、EntityType 属性ではエンティティ型の完全修飾名が使用されます。
- プロパティ名は、 上の DefiningQuery 要素の SQL ステートメントによって返される列名に対応します。
- この例では、エンティティ キーは、一意のキー値を確保するために 3 つのプロパティで構成されています。
<EntityType Name="GradeReport">
<Key>
<PropertyRef Name="CourseID" />
<PropertyRef Name="FirstName" />
<PropertyRef Name="LastName" />
</Key>
<Property Name="CourseID"
Type="int"
Nullable="false" />
<Property Name="Grade"
Type="decimal"
Precision="3"
Scale="2" />
<Property Name="FirstName"
Type="nvarchar"
Nullable="false"
MaxLength="50" />
<Property Name="LastName"
Type="nvarchar"
Nullable="false"
MaxLength="50" />
</EntityType>
注
後で [モデルの更新ウィザード ] ダイアログを実行すると、クエリの定義など、ストレージ モデルに加えられた変更が上書きされます。
エンティティ型をモデルに追加する
この手順では、EF デザイナーを使用してエンティティ型を概念モデルに追加します。 次の点に注意してください。
- エンティティの 名前 は、上記の EntitySet 要素の EntityType 属性の値に対応します。
- プロパティ名は、上記の DefiningQuery 要素の SQL ステートメントによって返される列名に対応します。
- この例では、エンティティ キーは、一意のキー値を確保するために 3 つのプロパティで構成されています。
EF デザイナーでモデルを開きます。
DefiningQueryModel.edmx をダブルクリックします。
次のメッセージに 対して「はい」 と言います。
モデルを編集するためのデザイン 画面を提供するエンティティ デザイナーが表示されます。
- デザイナー画面を右クリックし、[ Add New->Entity...] を選択します。
- エンティティ名に GradeReport を指定し、Key プロパティに CourseID を指定します。
- GradeReport エンティティを右クリックし、[Add New->Scalar Property] を選択します。
- プロパティの既定の名前を FirstName に変更します。
- 別のスカラー プロパティを追加し、名前に LastName を指定します。
- 別のスカラー プロパティを追加し、名前に Grade を指定します。
- プロパティ ウィンドウで、成績の タイプ プロパティを 小数 に変更します。
- FirstName プロパティと LastName プロパティを選択します。
- [ プロパティ ] ウィンドウで、 EntityKey プロパティの値を True に変更します。
その結果、次の要素が .edmx ファイルの CSDL セクションに追加されました。
<EntitySet Name="GradeReport" EntityType="SchoolModel.GradeReport" />
<EntityType Name="GradeReport">
. . .
</EntityType>
定義クエリをエンティティ型にマップする
この手順では、[マッピングの詳細] ウィンドウを使用して、概念エンティティの種類とストレージ エンティティの種類をマップします。
- デザイン 画面で GradeReport エンティティを右クリックし、[ テーブル マッピング] を選択します。
[ マッピングの詳細] ウィンドウが表示されます。 -
[<] ドロップダウンリスト (「テーブル」の下にあります) から GradeReport を選択します。
概念とストレージ GradeReport エンティティの種類の間の既定のマッピングが表示されます。
その結果、 EntitySetMapping 要素が .edmx ファイルのマッピング セクションに追加されます。
<EntitySetMapping Name="GradeReports">
<EntityTypeMapping TypeName="IsTypeOf(SchoolModel.GradeReport)">
<MappingFragment StoreEntitySet="GradeReport">
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="Grade" ColumnName="Grade" />
<ScalarProperty Name="CourseID" ColumnName="CourseID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
- アプリケーションをコンパイルします。
コードで定義クエリを呼び出す
GradeReport エンティティ型を使用して、定義クエリを実行できるようになりました。
using (var context = new SchoolEntities())
{
var report = context.GradeReports.FirstOrDefault();
Console.WriteLine("{0} {1} got {2}",
report.FirstName, report.LastName, report.Grade);
}
.NET