複合型
WCF RIA サービスでの複合型のサポートにより、エンティティ プロパティのセットを単一の (複合) プロパティにカプセル化することができます。これらの型を使用すると、関連するプロパティの特定のサブセットがエンティティに含まれている場合に、そのエンティティを簡素化できます。複合型は、プロパティの同じサブセットを共有する別の (異なる) エンティティで再利用することもできます。複合型の一般的な例としては、住所の指定に必要なエンティティ プロパティを収集する Address
があります。たとえば、Address
型のプロパティ セットには、StreetAddress
、City
、StateProvince
、PostalCode
、Country
などのエンティティ プロパティが含まれます。この複合型は Customer
エンティティおよび Contact
エンティティの両方で使用できますが、各エンティティがこのプロパティ セットを共有している必要があります。したがって、定義した後は、Address
カスタム型は他のエンティティでもエンティティ プロパティ自体として使用できます。
複合型は、複合型のプロパティでもあるプロパティを含むことができるため、エンティティ型またはその他の複合エンティティに、構造化された豊富なプロパティを定義するためのテンプレートです。複合型はその名前空間内で一意の名前を指定する必要があり、オプションで 1 つ以上のプロパティの形式のデータを含むことができます。複合型には ID がなく、独立して存在できないため、エンティティ型またはその他の複合型のプロパティとしてのみ存在できます。複合型は正規型であり、インスタンス化してコードで使用できますが、エンティティ型のように直接照会したり、データベースに保持することはできません。また、複合型はアソシエーションに参加できないという点でもエンティティと異なります。したがって、ナビゲーション プロパティは、エンティティ型とは異なり複合型では定義できません。
WCF RIA サービス V1.0 SP1 には、エンティティ型以外の複合型のサポートが追加されました。具体的には、ComplexObject 基本クラスから派生する複合型のコード生成がサポートされています。クライアント プロキシの生成のサポートは、RIA サービス のエンティティに対するサポートと同様に充実しています。エンティティと同様にメタデータもサポートされており、詳細な検証、変更の追跡、編集セッション、および複合型のパラメーターのサポートも同様に用意されています。つまり、Address
などのカスタム型は、エンティティ プロパティとして使用できるだけでなく、ドメイン サービス メソッドのパラメーターまたは戻り値としても使用できるようになりました。
複合型の定義と表現
ここでは、Entity Data Model (EDM) デザイナーを使用してエンティティ プロパティのセットをエンティティ型から複合型にカプセル化する方法について説明します。Entity Data Model (EDM) では、概念スキーマ定義言語 (CSDL) と呼ばれるドメイン固有言語 (DSL) を使用して概念モデルを定義します。デザイナーの基礎になっている CSDL での複合型の XML 表現について説明します。
このトピックでは、「チュートリアル: RIA Services ソリューションの作成」を完了しているか、同等の知識を持っていて、既存の RIA サービス ソリューションが使用できることを前提としています。
デザイナーを使用した複合型の作成
「チュートリアル: RIA Services ソリューションの作成」を実行して作成した RIAServicesExample ソリューションを開き、Entity Framework デザイナーで AdventureWorksModel.edmx ファイルを開きます (既定で実行されます)。
Address
エンティティから、AddressLine1
、AddressLine2
、City
、StateProvince
、CountryRegion
、およびPostalCode
の各プロパティを選択します。いずれかのプロパティを右クリックし、[新しい複合型へのリファクター] をクリックします。これにより、モデル ブラウザーが開き、作成した複合型 (既定では ComplexType1 という名前) が AdventureWorksModel.edmx の ComplexTypes フォルダーに表示されます。モデル ブラウザーで指定した名前は、実際には新しい ComplexProperty の型です。この新しい複合プロパティによってカプセル化されたサブプロパティが、モデル ブラウザーに表示されます。
モデル ブラウザーで
ComplexType1
を選択し、名前をMailAddress
に変更します。これが新しい ComplexProperty の型となります。これを検証するには、Address
エンティティで ComplexProperty を選択し、[プロパティ] ウィンドウで型を確認します。[プロパティ] ウィンドウで、新しい
MailAddress
型の [名前] を MailAddress に変更します。この新しい名前はデザイナーにも表示されます。デザイナーで
MailAddress
を選択して右クリックし、[テーブル マッピング] をクリックして [マッピングの詳細] テーブルにアクセスします。このテーブルは、プロパティがデータベースのテーブル列にどのようにマップされるかを示します。
複合型の XML 表現
RIA サービス では、データ モデルを指定するために概念スキーマ定義言語 (CSDL) が使用されます。これは XML ベースの言語であり、データ駆動型アプリケーションの概念モデルを構成するエンティティ、リレーションシップ、および関数を記述します。新しい MailAddress
型の指定は、XML の CSDL セクションで行います。
このセクションにアクセスするには、ソリューション エクスプローラーで AdventureWorksModel.edmx を右クリックし、[プログラムから開く] をクリックして、[XML (テキスト) エディター] をクリックします。Visual Studio 2010 では XML 表現を開くためにデータ モデルのデザイン ビューを閉じる必要があるので、[はい] をクリックして承認します。次のように、新しい MailAddress
プロパティが <EntityType Name=”Address”>
要素内に指定されます。
<Property Name="MailAddress" Type="AdventureWorksLTModel.MailAddress" Nullable="false" />
アソシエーションが定義されているセクションの下で、MailAddress
プロパティが独自の要素に定義されます。
<ComplexType Name="MailAddress">
<Property Type="String" Name="AddressLine1" Nullable="false" MaxLength="60" FixedLength="false" Unicode="true" />
<Property Type="String" Name="AddressLine2" MaxLength="60" FixedLength="false" Unicode="true" />
<Property Type="String" Name="City" Nullable="false" MaxLength="30" FixedLength="false" Unicode="true" />
<Property Type="String" Name="StateProvince" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Type="String" Name="CountryRegion" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Type="String" Name="PostalCode" Nullable="false" MaxLength="15" FixedLength="false" Unicode="true" />
</ComplexType>
<ComplexType>
要素内に <Key>
要素はありません。これは、<EntityType>
要素内にあるためです。
別のエンティティでの複合型の再利用
住所プロパティの同じセットを含む Manufacturer
エンティティ型がある場合、MailAddress
という複合型にそれらのプロパティをカプセル化できます。複合型の作成で行ったように [新しい複合型へのリファクター] を使用し、[プロパティ] ウィンドウで型と名前を変更します。フィールドはそれぞれのエンティティを指すようになります。たとえば、Address
エンティティの MailAddress
の City
フィールドは Address.City
にマップし、このフィールドは Manufacturer
エンティティ型の Manufacturer.City
にマップします。プロパティがデータベースの正しい列にマップすることを確認するには、[マッピングの詳細] テーブルを使用します。