方法: POCO 定義のエンティティを使用するドメイン サービスを作成する
このトピックでは、WCF RIA サービスを使用して、Plain Old CLR Objects (POCO) を使用するドメイン サービスを作成する方法について説明します。目的は、非常に基本的な POCO ベースの RIA サービス アプリケーションを作成する方法を示すことです。具体的には、手順のさまざまなステップで RIA サービス ツール (ウィザードとダイアログ ボックス) を使用した場合にどのような現象が発生するかを説明します。POCO から抽出されるデータは、移植性やデータのセキュリティ、またはテストを目的として、バックエンド データベースに対する依存関係からアプリケーションを解放するために使用できます。自動的に生成されるクライアント コードは、Link to SQL または Link to Entity Framework と同様に、POCO 定義のエンティティを使用して RIA サービス で完全にサポートされます。実際は、RIA サービス ドメイン サービスはデータ ソースに依存しないため、この POCO クラスは、ドメイン サービス自体を変更することなく、データベースなど他の一部のソースからデータにアクセスするコンポーネントによって後から置き換えることができます。
ここで説明している手順では、WCF RIA サービスに加え、Visual Studio 2010 や Silverlight の開発者向けランタイムと SDK など、前提条件となっているいくつかのプログラムが適切にインストールおよび構成されている必要があります。ただし、WCF RIA サービス ツールキットは必要ありません。これらの各前提条件を満たしているかどうかを確認するための詳細な手順については、「WCF RIA Services の前提条件」ノード内のトピックを参照してください。このチュートリアルを進める前に、トピックに記載されている必要なプログラムに関する手順に従って、発生する問題をできるだけ最小限に抑えるようにします。
RIA サービス ソリューションの作成
Visual Studio 2010 で、[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックして、新しい RIA サービス プロジェクトを作成します。
[新しいプロジェクト] ダイアログ ボックスが表示されます。
[インストールされたテンプレート] の [Silverlight] で [Silverlight アプリケーション] テンプレートをクリックし、新しいプロジェクトに RIAServicesPocoExample という名前を付けます。
[OK] をクリックします。
[新しい Silverlight アプリケーション] ダイアログ ボックスが表示されます。
ダイアログ ボックスの下部にある [WCF RIA サービスを有効にする] チェック ボックスをオンにします。このチェック ボックスをオンにすると、クライアント プロジェクトとサーバー プロジェクトの間に RIA サービス リンクが作成されます。この接続を有効にするために、次の参照がクライアント プロジェクトに追加されます。
System.ComponentModel.DataAnnotations
System.Runtime.Serialization
System.ServiceModel.dll
System.ServiceModel.DomainServices.Client
System.ServiceModel.DomainServices.Client.Web
System.ServiceModel.Web.Extensions
System.Windows.Browser
[OK] をクリックして、ソリューションを作成します。
このソリューションには、クライアント プロジェクトとサーバー プロジェクトの 2 つのプロジェクトが含まれています。
RIAServicesPocoExample: プレゼンテーション層の作成に使用する Silverlight コードが含まれるクライアント プロジェクトです。
RIAServicesPocoExample.Web: 中間層のコードが含まれるサーバー プロジェクトです。
ドメイン サービスの作成
サーバー プロジェクトを右クリックし、[追加] をポイントして、[新しい項目] をクリックします。
カテゴリの一覧で、[Web] をクリックし、[DomainService クラス] テンプレートをクリックします。
クラスに SovereignDomainService.cs (または SovereignDomainService.vb) という名前を付けます。
[追加] をクリックします。
[新しいドメイン サービス クラスの追加] ダイアログ ボックスが表示されます。
[クライアント アクセスを有効にする] チェック ボックスがオンになっていることを確認します。
[使用できる DataContext/ObjectContext クラス] ボックスの一覧に表示される唯一のオプションは [<空のドメイン サービス クラス>] エンティティであり、[メタデータ用の関連クラスを生成する] チェック ボックスをオンにすることはできません。これは、サービスを関連付けるために使用できるデータ コンテキストがないためです。
[OK] をクリックします。
このウィザードでは、いくつかの処理が実行されます。新しい SovereignDomainService.cs (または SovereignDomainService.vb) ファイルに、関連付けられた属性と
using
ステートメントを使用して空のSovereignDomainService
クラスが生成されます。また、サービス プロジェクトに 4 つのアセンブリ参照が追加され、Web.config ファイルに構成要素が追加されます。これを確認するために、SovereignDomainService.cs (または SovereignDomainService.vb) ファイルが自動的に開かれていない場合は、このファイルを開きます。このファイルには、次の特性があります。
次のように
using
ステートメントが追加されています。using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server
SovereignDomainService
クラスは DomainService クラスから派生します。このクラスは、RIA サービス フレームワークの抽象基本クラスです。これは RIA サービス で公開されるすべてのドメイン サービスの基本クラスです。SovereignDomainService
クラスは、EnableClientAccessAttribute 属性でマークされ、クライアント層に表示されることを示します。
ウィザードによって次の参照がサービス プロジェクトに追加されています。
System.ComponentModel.DataAnnotations
System.Runtime.Serialization
System.ServiceModel.DomainServices.Hosting
System.ServiceModel.DomainServices.Server
最後に、Web.config ファイルを開き、ウィザードによって追加された新しい要素を確認します。
<configuration> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="DomainServiceModule" preCondition="managedHandler" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </modules> <validation validateIntegratedModeConfiguration="false" /> </system.webServer> <system.web> <httpModules> <add name="DomainServiceModule" type="System.ServiceModel.DomainServices.Hosting.DomainServiceHttpModule, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </httpModules> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> </configuration>
.NET Framework 4.0 を対象としている構成要素を除き、これらの各要素は [新しいドメイン サービス クラスの追加] ダイアログ ボックスによって追加されています。これらの要素により、インターネット インフォメーション サービス (IIS) のさまざまなホスト オプションおよび ASP.NET のオプションが有効になります。
ウィザードによって、IIS 7 のホストで必要となる
<modules>
要素が<system.webserver>
セクションに追加されます。ウィザードによって、IIS 6 のホストで必要となる
<httpModules>
要素の<add>
要素がsystem.web
セクションに追加されます。RIA サービス ドメイン サービスは Windows Communication Foundation (WCF) サービスであり、ASP.NET でホストされる場合は、ASP.NET 互換モードでホストされる必要があります。この要件をコードで設定することはできず、Web.config ファイルで指定する必要があります。ASP.NET 互換モードを有効にするには、
<system.serviceModel>
セクションの<ServiceHostingEnvironment>
要素でaspNetCompatibilityEnabled
プロパティを true に設定します。
POCO クラスの追加
この手順では、POCO クラスをエンティティ型として使用することを RIA サービス フレームワークに指示する方法について説明します。エンティティ型はアプリケーションのデータ モデルにデータ構造を提供し、各エンティティ型には一意のエンティティ キーが必要です。データの構造体は、データに含まれるプロパティのセットによって指定されます。エンティティ キーの提供は、同じ型の他のエンティティからエンティティを区別する各エンティティ オブジェクトの一意の名前を提供する必要がある、1 つまたは複数のプロパティの代理となることによって行われます。通常、この指定はいくつかの異なるメタデータを使用して行います。この手順では、プロパティに
[Key]
属性を適用します。この属性の適用では、POCO クラスのインスタンスがエンティティ オブジェクトであることを RIA サービス フレームワークに指示しています。SovereignDomainSevice.cs ファイルを開きます。
RIAServicesPocoExample.Web 名前空間のスコープ内の、スタブとして作成された
SovereignDomainService
クラスの下に、次のSovereign
クラスのコードを追加します。public class Sovereign { [Key] public int UniqueId { get; set; } public string Name { get; set; } public string House { get; set; } public string Dominion { get; set; } public int ReignStart { get; set; } public int ReignEnd { get; set; } public string Sobriquet { get; set; } }
この例では、
UniqueId
プロパティは、Sovereign
型の各エンティティ オブジェクトに一意の名前を提供するエンティティ キーです。[Key]
属性は System.ComponentModel.DataAnnotations アセンブリで定義されていますが、この属性は既にサーバー プロジェクトに追加されており、この属性を含む対応する名前空間のusing
ステートメントも同様です。エンティティ キーはメタデータ ファイルまたはその他の方法で指定することもできますが、これは POCO クラスでエンティティ キーを直接指定する便利な方法です。Sovereign
インスタンスのリストを返すSovereign
クラスにFetchSovereigns()
メソッドを追加します。public List<Sovereign> FetchSovereigns() { List<Sovereign> sovereignList = new List<Sovereign> { new Sovereign() {UniqueId = 1, Name = "John", House = "Plantagenet", Dominion = "Angevin Empire", ReignStart = 1167, ReignEnd = 1216, Sobriquet = "Lackland" }, new Sovereign() {UniqueId = 2, Name = "Charles", House = "Stuart", Dominion = "England, Scotland, & Ireland", ReignStart = 1625, ReignEnd = 1649, Sobriquet = "The Martyr" }, new Sovereign() {UniqueId = 3, Name = "William", House = "Dunkeld", Dominion = "Scotland", ReignStart = 1165, ReignEnd = 1249, Sobriquet = "The Lion" }, new Sovereign() {UniqueId = 4, Name = "Elizabeth", House = "Tudor", Dominion = "England", ReignStart = 1555, ReignEnd = 1609, Sobriquet = "The Virgin Queen" }, new Sovereign() {UniqueId = 5, Name = "Ivan", House = "Vasilyevich", Dominion = "Russia", ReignStart = 1533, ReignEnd = 1584, Sobriquet = "The Terrible" }, new Sovereign() {UniqueId = 6, Name = "Charles", House = "Valois", Dominion = "France", ReignStart = 1380, ReignEnd = 1422, Sobriquet = "The Mad" } }; return sovereignList; }
ドメイン サービスの定義
この手順では、POCO 定義のエンティティからデータを取得するために、クライアントからアクセスできるようになるドメイン サービスでクエリを作成する方法について説明します。RIA サービス フレームワークでは、クライアントでクエリとして使用できるようになるメソッドを認識する必要があり、これを実現するために使用する名前付け規則があります。
Get
で始まるメソッド名で、IEnumerable<EntityType>
またはIQueryable<EntityType>
を返すものは、RIA サービス フレームワークによってクエリとして認識されます。ヒント : IQueryable は、IEnumerable から派生します。POCO 定義のエンティティなどのインメモリ コレクションには IEnumerable を使用し、SQL データベースなどの基になるデータ ソースやリモート データ ソースにアクセスするときは IQueryable を使用します。 GetSovereign()
メソッドをSovereignDomainService
クラスに追加します。public IEnumerable<Sovereign> GetSovereigns() { Sovereign sovereign = new Sovereign(); return sovereign.FetchSovereigns(); }
コレクションからすべての Sovereign エンティティが返されます。ただし、通常はエンティティのサブセットのみを返すようにします。これを示すため、
sovereign.ReignEnd
<= 1500 というコードを追加して、中世に君臨した君主のみがリストから返されるようにこのクエリを変更します。このコードを次に示します。public IEnumerable<Sovereign> GetSovereignsByReignEnd(int ReignedBefore) { Sovereign sovereign = new Sovereign(); return sovereign.FetchSovereigns().Where<Sovereign>(p => p.ReignEnd <= 1500); }
ソリューションをビルドして (Ctrl キーと Shift キーを押しながら B キーを押します)、自動生成クライアント プロキシ コードを作成します。
ソリューション エクスプローラーで、RIAServicesPocoExample クライアント プロジェクトを選択し、ウィンドウの上部にある [すべてのファイルを表示] をクリックして、Generated_Code フォルダーの RIAServicesPocoExample.Web.g.cs ファイルを確認します。このファイル内の自動生成コードを調べ、次の項目について確認します。
WebContextBase クラスから派生する
WebContext
クラスが生成され、アプリケーション コンテキストの管理に使用されます。ドメイン サービスによって公開されるエンティティに対して、Entity クラスから派生する
Sovereign
クラスが生成されます。クライアント プロジェクトのSovereign
エンティティ クラスは、サーバーのSovereign
エンティティと一致します。DomainContext クラスから派生する
SovereignDomainContext
クラスが生成されます。このクラスには、ドメイン サービスで作成されたクエリ メソッドに対応する、GetSovereignsByReignEndQuery
という名前のメソッドがあります。
自動コード生成の詳細については、「クライアント コード生成」を参照してください。コード生成のカスタマイズ方法の詳細については、「生成されたコードのカスタマイズ」を参照してください。
Silverlight クライアントでのクエリ結果の表示
MainPage.xaml を開きます。
左側のツールボックスから XAML ビューの Grid 要素内に DataGrid コントロールをドラッグします。
DataGrid コントロールをツールボックスからドラッグすると、名前空間の
using System.Windows.Controls
ステートメントが MainPage.xaml.cs ファイルに追加され、System.Windows.Controls.Data アセンブリおよび System.Windows.Controls.Data.Input アセンブリへの参照が自動的にクライアント プロジェクトに追加されます。注意 : DataGrid をツールボックスからドラッグせずに追加する場合は、アセンブリへの参照をクライアント プロジェクトに追加し、分離コード ファイルに using ステートメントを手動で追加する必要があります。 次の XAML に示すように、
AutoGeneratedColums
の値を True に変更し、DataGrid
要素にSovereignGrid
という名前を付け、Height
とWidth
の値を調整します。<Grid x:Name="LayoutRoot" Background="White"> <sdk:DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="157,86,0,0" Name="SovereignGrid" VerticalAlignment="Top" Width="600" /> </Grid>
MainPage.xaml.cs ファイルを開きます。
using
(C#) またはImports
(Visual Basic) の 2 つのステートメント (using RIAServicesPocoExample.Web;
およびusing System.ServiceModel.DomainServices.Client;
) を追加します。RIAServicesPocoExample.Web 名前空間は、RIAServicesPocoExample.Web.g.cs (または RIAServicesPocoExample.Web.g.vb) でクライアント プロジェクトに対して生成されたコードを含む名前空間です。
SovereignDomainContext
をインスタンス化するには、コード行private SovereignDomainContext _sovereignContext = new SovereignDomainContext();
をMainPage
クラスに追加します。顧客エンティティを取得するには、
LoadOperation<Sovereign> loadOp = this._sovereignContext.Load(this._sovereignContext.GetSovereignsByReignEndQuery(1500));
のように、LoadOperation を使用してGetSovereignsQuery
メソッドを呼び出します。DataGrid に読み込まれたエンティティを
SovereignGrid.ItemsSource = loadOp.Entities;
にバインドします。まとめると、MainPage.xaml.cs ファイルには次のコードが含まれます。
//Namespaces added using RIAServicesPocoExample.Web; using System.ServiceModel.DomainServices.Client; namespace RIAServicesPocoExample { public partial class MainPage : UserControl { private SovereignDomainContext _sovereignContext = new SovereignDomainContext(); public MainPage() { InitializeComponent(); LoadOperation<Sovereign> loadOp = this._sovereignContext.Load(this._sovereignContext.GetSovereignsByReignEndQuery(1500)); SovereignGrid.ItemsSource = loadOp.Entities; } } }
アプリケーションを実行します (F5 キーを押します)。
中世の君主 (西暦 1500 年以前に終了した治世) のみのプロパティをアルファベット順で表示するテーブルが、ブラウザーに表示されます。