次の方法で共有


Silverlight アプリケーションの作成 (WCF Data Services)

重要

Windows Phone アプリケーションに対して、Silverlight の WCF Data Services 5.0 クライアント ライブラリはサポートされません。代わりに、Windows Phone 7.1 SDK に含まれている Windows Phone の OData クライアント ライブラリを使用する必要があります。詳細については、「Windows Phone の Open Data Protocol (OData) クライアント」を参照してください。現在は、OData v3 をサポートする Windows Phone のクライアント ライブラリはありません。

Silverlight の WCF Data Services クライアント ライブラリが OData プロトコルのバージョン 3 をサポートするデータ サービスへの HTTP 要求を生成し、OData 応答フィードのデータをクライアントのオブジェクトに変換します。 クライアント ライブラリの 2 つの主要なクラスは、DataServiceContext クラスと DataServiceQuery<TElement> クラスです。 DataServiceContext クラスは、特定のデータ サービスに対して実行される操作をカプセル化します。 OData ベースのサービスはステートレスです。 ただし、DataServiceContext は、データ サービスとの対話操作間におけるクライアントのエンティティの状態を保持します。 これにより、クライアントは変更の追跡、ID 管理などの機能をサポートできます。 DataServiceQuery<TElement> クラスは、特定のエンティティ セットに対するクエリを表します。 詳細については、「WCF Data Services クライアント ライブラリ」を参照してください。 Northwind サンプル データ サービスのフィードを使用する実際のアプリケーションの例については、「OData フィードの使用」を参照してください。

注意

Silverlight の WCF Data Services クライアント ライブラリを使用する場合、サービスへの要求はすべて非同期で行われます。詳細については、「非同期操作 (WCF Data Services)」を参照してください。

このトピックは、次のセクションで構成されています。

クライアント データ サービス クラスの生成

Visual Studio の [サービス参照の追加] ダイアログ ボックスを使用して、OData フィードを公開するサービスに参照を追加できます。 詳細については、「クライアント データ サービス クラスの生成 (WCF Data Services)」を参照してください。 クライアント データ サービス クラスは、コマンド プロンプトで DataSvcUtil.exe ツールを使用して生成することもできます。 詳細については、「方法: クライアント データ サービス クラスを手動で生成する (WCF Data Services)」を参照してください。

注意

WCF Data Services 5.0 リリースをインストールすると、サービス参照の追加ツールによって、Silverlight に含まれている System.Data.Services.Client.dll バージョンではなく、クライアント ライブラリの Microsoft.Data.Services.Client.SL.dll バージョンに自動的に参照が追加されます。何らかの理由で Silverlight クライアントの以前のバージョンを使用する必要がある場合は、クライアント ライブラリの Silverlight バージョンに参照を手動で追加する必要があります。詳細については、「方法: クライアント データ サービス クラスを手動で生成する (WCF Data Services)」を参照してください。

リソースに対するアクセスと変更

Silverlight ベースのアプリケーションでは、データ サービスに対するすべての操作が非同期で行われます。 DataServiceContext クラスと DataServiceQuery<TElement> クラスでそれぞれ Begin および End で始まるメソッドのペアを使用して、非同期操作を実行します。 Begin メソッドは、操作が完了したときにサービスが呼び出すデリゲートを登録します。 End メソッドは、完了した操作からのコールバックを処理するために登録されたデリゲートで呼び出す必要があります。 End メソッドを呼び出して非同期操作を完了するときは、操作を開始するために使用したものと同じ DataServiceQuery<TElement> または DataServiceContext インスタンスから呼び出しを行う必要があります。 各 Begin メソッドは、状態オブジェクトをコールバックに渡すことができる state パラメーターを受け取ります。 この状態オブジェクトは、コールバックで指定された IAsyncResult として取得され、対応する End メソッドを呼び出して非同期操作を完了するために使用されます。 たとえば、インスタンスで BeginExecute メソッドを呼び出すときに DataServiceQuery<TElement> インスタンスを state パラメーターとして指定した場合、同じ DataServiceQuery<TElement> インスタンスが IAsyncResult として返されます。 この DataServiceQuery<TElement> のインスタンスは、EndExecute メソッドを呼び出してクエリ操作を完了するために使用されます。 詳細については、「非同期操作 (WCF Data Services)」を参照してください。

Silverlight の WCF Data Services クライアント ライブラリは、ネットワーク プロトコルを使用してデータ サービスに非同期にアクセスするため、Dispatcher クラスの BeginInvoke メソッドを使用して、応答操作を Silverlight ベース アプリケーションのメイン アプリケーション スレッド (UI スレッド) に正しくマーシャリングする必要があります。 詳細については、「Synchronizing Data for Multithreading」を参照してください。

リソースのクエリ

Silverlight の WCF Data Services クライアント ライブラリを使用すると、統合言語クエリ (LINQ) を含む、使い慣れた .NET Framework プログラミング パターンを使用して OData データ サービスに対してクエリを実行できます。 DataServiceQuery<TElement> または DataServiceContext で BeginExecute メソッドが呼び出されると、クライアント ライブラリは、クエリまたは URI (Uniform Resource Identifier) を HTTP GET 要求メッセージに変換します。 クライアント ライブラリは対応する応答メッセージを受け取り、クライアント データ サービス クラスのインスタンスに変換します。 これらのクラスは、DataServiceQuery<TElement> が属する DataServiceContext によって追跡されます。 詳細については、「方法: 非同期データ サービス クエリを実行する (WCF Data Services)」を参照してください。

一部のシナリオでは、クエリによって返されるフィードの数だけではなく、エンティティ セット内のエンティティの合計数を知っておくと役立ちます。 このセット内のエンティティの合計数がクエリ結果に含まれるように要求するには、DataServiceQuery<TElement>IncludeTotalCount メソッドを呼び出します。 この場合、返された QueryOperationResponse<T>TotalCount プロパティが、セット内のエンティティの合計数を返します。 また、AddQueryOption メソッドを使用して、OData でサポートされるその他のクエリ オプションをクエリに追加することもできます。 詳細については、「データ サービスのクエリ (WCF Data Services)」を参照してください。

LINQ クエリ

DataServiceQuery<TElement> クラスは LINQ で定義された IQueryable<T> インターフェイスを実装するので、Silverlight の WCF Data Services クライアント ライブラリは、エンティティ セット データに対する LINQ クエリを、データ サービス リソースに対して評価されるクエリ式を表す URI に変換できます。 たとえば、次の LINQ クエリは、customerId ボックスでユーザーによって指定された CustomerID プロパティ値でフィルター処理された Order エンティティのコレクションであるフィードを返します。

' Define a query that returns orders for a give customer.
Dim query = From orderByCustomer In context.Orders _
                Where orderByCustomer.Customer.CustomerID = _
                Me.customerId.Text _
                Select orderByCustomer
// Define a query that returns orders for a give customer.
var query = from orderByCustomer in context.Orders
            where orderByCustomer.Customer.CustomerID == this.customerId.Text
            select orderByCustomer;

遅延コンテンツの読み込み

WCF Data Services の既定では、クエリが返すデータの量が制限されます。 その一方で、関連エンティティ、ページングされた応答データ、およびバイナリ データ ストリームを含む追加データをデータ サービスから必要に応じて明示的に読み込むことができます。 クエリを実行すると、アドレス指定したエンティティ セット内のエンティティだけが返されます。 たとえば、Northwind データ サービスに対するクエリが Customers エンティティを返す場合、Customers と Orders の間にリレーションシップがあっても、既定では関連 Orders エンティティは返されません。 関連エンティティは元のクエリを使用 (一括読み込み) するか、各エンティティ ベース (明示的な読み込み) で読み込むことができます。 詳細については、「遅延コンテンツの読み込み (WCF Data Services)」を参照してください。 Silverlight クライアントと DataServiceCollection<T> を使用する場合、LoadAsync を呼び出すことによって、ナビゲーション プロパティから関連エンティティのコレクションを読み込むことができます。

ヒント

関連エンティティの読み込みパターンを決定する場合、メッセージ サイズとデータ サービスへの要求の数がパフォーマンスに与える影響のバランスを考慮してください。

データ サービスでページングが有効になっている場合、返されたエントリの数がページングの制限を超えたときは、以降のデータ ページをデータ サービスから明示的に読み込む必要があります。 ページングが発生する時期を事前に確認することはできないため、ページングされた OData フィードを適切に処理できるように、Silverlight クライアント アプリケーションを有効にしておくことをお勧めします。 ページングされた応答の処理方法の例については、「方法: データ サービスのデータのコントロールへのバインド (Silverlight クライアント)」および「データ サービスのクエリ (WCF Data Services)」を参照してください。

クエリ投影

射影は、エンティティの特定のプロパティのみが応答で返されるように指定することにより、クエリによって返される OData フィードのデータ量を減らすためのメカニズムを提供します。 詳細については、OData: Select システム クエリ オプション ($select) の説明を参照してください。 select 句 (Visual Basic の場合は Select) を使用して、projection 句を LINQ クエリに追加できます。 返されたエンティティ データは、クライアント上のエンティティ型またはエンティティ型以外に射影できます。 エンティティ型以外に加えられた変更は、データ サービスに保存できません。 たとえば、次の LINQ クエリは Customer データをクライアントの新しい CustomerAddress エンティティ型に射影します。

Dim query = From c In context.Customers _
                    Where c.Country = "Germany" _
                    Select New CustomerAddress With
                        {.CustomerID = c.CustomerID, _
                         .Address = c.Address, _
                         .City = c.City, _
                         .PostalCode = c.PostalCode, _
                         .Country = c.Country _
                        }
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress
            {
                CustomerID = c.CustomerID,
                Address = c.Address,
                City = c.City,
                PostalCode = c.PostalCode,
                Country = c.Country
            };

重要

射影された型に対して行った更新を保存すると、データ サービスでデータの損失が発生する場合があります。詳細については、WCF Data Services クライアント ドキュメントの「射影時の注意事項」を参照してください。

詳細については、「方法: データ サービス クエリ結果の射影 (Silverlight クライアント)」を参照してください。

リソースの変更と変更の保存

クライアントでは、DataServiceContext に次のメソッドを手動で実行して報告する、エンティティへの変更が追跡されます。

これらのメソッドを使用すると、クライアントは、追加および削除されたエンティティの追跡に加えて、プロパティ値に対して行われた変更やエンティティ インスタンス間のリレーションシップに対して行われた変更を追跡できます。 [サービス参照の追加] ダイアログ ボックスを使用してクライアント データ サービス クラスを生成すると、生成された DataServiceContext クラスの各エンティティに対して AddTo メソッドも作成されます。 これらのメソッドを使用することにより、新しいエンティティ インスタンスをエンティティ セットに追加して、コンテキストへの追加を報告できます。 追跡されたこれらの変更は、BeginSaveChanges メソッドおよび EndSaveChanges メソッドが呼び出されたときに、非同期でデータ サービスに送り返されます。

AddObject メソッド、または適切な AddTo メソッドを使用して新しいエンティティを追加する場合、新しいエンティティと関連エンティティの間のリレーションシップは自動的には定義されません。 エンティティ インスタンス間のリレーションシップを作成および変更し、クライアント ライブラリにこれらの変更をデータ サービスに反映できます。 エンティティ間のリレーションシップは、モデル内の関連付けとして定義されています。また、DataServiceContext は、各リレーションシップをコンテキスト内のリンク オブジェクトとして追跡します。 WCF Data Services は、DataServiceContext クラスで、これらのリンクを作成、変更、および削除する以下のメソッドを提供します。

詳細については、「データ サービスの更新 (WCF Data Services)」を参照してください。

バイナリ データの操作

OData は、バイナリ データが属するエンティティ以外のバイナリ データにアクセスするためのメカニズムを定義します。 このようにして、OData サービスは、メディア リンク エントリに属するメディア リソースとして大きなバイナリ データを公開できます。 Silverlight の WCF Data Services クライアントは、OData サービスのメディア リソースをバイナリ ストリームとして使用できます。 バイナリ ストリームにアクセスするには、メディア リンク エントリであるエンティティを追跡している DataServiceContext インスタンスで BeginGetReadStream メソッドを呼び出します。 この非同期メソッドは、コールバックが返す DataServiceContext インスタンスで EndGetReadStream メソッドが呼び出されたときに、DataServiceStreamResponse オブジェクトを返します。 同様に、SetSaveStream メソッドを呼び出し、BeginSaveChanges メソッドと EndSaveChanges メソッドを呼び出した後に、メディア リソースが OData サービスに送信されます。 詳細については、「方法: バイナリ データへのストリームとしてのアクセス (Silverlight クライアント)」を参照してください。

データ バインディング

Silverlight の WCF Data Services クライアントは、DataServiceCollection<T> クラスを使用して、制御するデータのバインディングをサポートします。 このクラスは、ObservableCollection<T> を継承するもので、項目がコレクションに追加された、またはコレクションから削除されたときに通知を行う動的なデータ コレクションを表します。 これらの通知によって、DataServiceContext が自動的に変更を追跡できるようになり、明示的に変更追跡メソッドを呼び出す必要はなくなります。 DataServiceCollection<T> は、DataServiceQuery<TElement> に基づいて定義されます。 実行されると、このクエリはコレクションのオブジェクトを提供します。

LoadAsync メソッドは、非同期にクエリを実行し、結果をコレクションに読み込むために使用されます。 このメソッドにより、結果が正しいスレッドにマーシャリングされるため、Dispatcher を使用する必要はありません。 データ バインディングに DataServiceCollection<T> のインスタンスを使用する場合、クライアントは DataServiceContext によって追跡されるオブジェクトとバインドされる UI 要素のデータとの同期を維持します。 バインディング コレクションのエンティティの変更を、手動で DataServiceContext に報告する必要はありません。 詳細については、「方法: データ サービスのデータのコントロールへのバインド (Silverlight クライアント)」を参照してください。

ドメイン間の実行

Silverlight では、別のドメインでホストされているサービスにアクセスすることができます。 この種類のアクセスは、ドメイン間ポリシー ファイルをサーバーに配置することによって、明示的に有効にする必要があります。 この機能は、Silverlight クライアントの HTTP 実装に含まれています。

注意

Silverlight クライアントによるドメイン間の状況での Web サービスへのアクセスを許可する場合に、セキュリティに関する重要な注意事項があります。詳細については、「HTTP Communication and Security with Silverlight」を参照してください。

Silverlight の WCF Data Services クライアントでは、データ サービスへのほとんどの要求に対して XMLHTTP 実装が使用されます。 ただし、ドメイン間要求を検出すると、WCF Data Services クライアントは自動的に Silverlight クライアントの HTTP 実装の使用に切り替えます。

注意

クライアントが自動的に HTTP 実装に切り替えるのは、HttpStack プロパティが Auto に設定されている場合だけです。

Silverlight ベースのアプリケーションからのドメイン間要求を許可するデータ サービスの構成方法の例については、「ドメイン間およびブラウザー外における ADO.NET Data Services Silverlight クライアント使用のシナリオ - I」の投稿を参照してください。 ドメイン間実行は、Silverlight 4 で新たにサポートされるようになりました。

ブラウザー外実行

ユーザーが Silverlight ベースのアプリケーションを自らのホスト Web ページからインストールし、ブラウザー外で実行できるように構成することができます。 Silverlight の WCF Data Services クライアントはブラウザー外実行をサポートします。 アプリケーションがブラウザー外で実行されていることを検出すると、WCF Data Services クライアントは自動的に Silverlight クライアントの HTTP 実装の使用に切り替えます。 これはドメイン間実行を検出したときの動作と同じですが、ドメイン間ポリシー ファイルは必要ありません。 詳細については、「Out-of-Browser Support」を参照してください。

クライアント認証

既定では、Silverlight の WCF Data Services クライアントは Web ブラウザーと同じクライアント資格情報を使用してデータ サービスへの要求を行い、認証は Web ブラウザーによって管理されます。 ただし、データ サービスへのアクセスにドメイン間要求が必要な場合、または Silverlight アプリケーションが Web ブラウザー外で実行されている場合、要求を行うときに資格情報を指定できます。 このようなシナリオでは、クライアントは自動的に Silverlight クライアントの HTTP 実装を使用して要求を発行し、認証には既定の資格情報が使用されます。 ただし、UseDefaultCredentials プロパティが false に設定されている場合、クライアントはデータ サービスへの認証を行うときに Credentials に割り当てられた ICredentials を使用します。

注意

ユーザー資格情報は実行時にのみ要求し、キャッシュしないようにする必要があります。資格情報は常に安全に格納する必要があります。

アプリケーションによる Silverlight クライアントの HTTP 実装の使用を必須にすることによって、資格情報を指定することもできます。 その場合は、HttpStack プロパティの値を ClientHttp に設定する必要があります。 次のコードを使用すると、データ サービスにアクセスするときに、実行中にユーザーから収集した資格情報が使用されます。

' Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp
context.UseDefaultCredentials = False
context.Credentials = _
    New NetworkCredential(userName, password, domain)
// Select the client HTTP stack and set the credentials.
context.HttpStack = HttpStack.ClientHttp;
context.UseDefaultCredentials = false;
context.Credentials = 
    new NetworkCredential(userName, password, domain);

Silverlight クライアントの HTTP 実装を使用しないときは、UseDefaultCredentials プロパティの値を false に設定すると、実行中に例外が発生します。 UseDefaultCredentials の値が true の場合は、Credentials プロパティが設定されていても、既定の資格情報が使用されます。

注意

基本認証およびダイジェスト認証で送信されるデータは暗号化されないため、敵対者がデータを見ることができます。また、基本認証の資格情報 (ユーザー名とパスワード) はクリア テキストで送信されるので、傍受される可能性があります。

詳細については、「方法: データ サービス要求のクライアント資格情報の指定 (Silverlight クライアント)」を参照してください。 Silverlight アプリケーションから ASP.NET フォーム認証を使用するデータ サービスへのアクセス方法の例については、「ドメイン間およびブラウザー外における ADO.NET Data Services Silverlight クライアント ライブラリ使用のシナリオ – II (フォーム認証)」の記事を参照してください。