次の方法で共有


DomainContext と操作

ここでは、WCF RIA サービス アプリケーションのクライアントでドメイン コンテキストを使用して、アプリケーションの中間層のドメイン サービスと通信する方法について説明します。クライアント プロジェクト内から直接ドメイン サービスと対話することはありません。代わりに、サーバー プロジェクトの各ドメイン サービスに対するドメイン コンテキスト クラスがクライアント プロジェクトに生成されます。使用するドメイン サービス メソッドに対応するドメイン コンテキスト クラスでメソッドを呼び出します。生成されるドメイン コンテキスト クラスは、DomainContext クラスから派生します。既定では、ドメイン コンテキストの名前には、ドメイン サービスの名前付けに使用される Service ではなく、Context が接尾辞として使用されます。たとえば、HRService という名前のドメイン サービスには、HRContext という名前の対応するドメイン コンテキストがあります。ドメイン サービス メソッドの定義の詳細については、「ドメイン サービス」を参照してください。

生成されるドメイン コンテキストには、次の 3 つのコンストラクター メソッドが含まれています。

  1. HTTP 経由でドメイン サービスと通信するために URI を埋め込む既定のコンストラクター。

  2. 代替 URI の指定を可能にするコンストラクター。

  3. カスタム DomainClient 実装を指定できるようにするコンストラクター。通常、このコンストラクターは、単体テスト、またはカスタム トランスポート レイヤーへのリダイレクトに使用されます。

DomainContext クラスでは、クエリ、送信、および呼び出しの各ドメイン操作がサポートされています。各種操作には、進行中の非同期操作を表す、対応するクラスがあります。このようなクラスとしては、LoadOperationSubmitOperation、および InvokeOperation があります。

EntitySet オブジェクトは、クライアントから許可されている操作 (挿入、更新、または削除) を示すプロパティが指定された状態で、ドメイン コンテキスト内に生成されます。

クエリ

通常、ドメイン コンテキスト内のクエリ メソッドの名前は、ドメイン サービスのクエリ メソッドに Query という接尾辞を加えたものと同じです。たとえば、ドメイン コンテキスト内の GetCustomersQuery メソッドは、ドメイン サービス内の GetCustomers メソッドから生成されます。ドメイン コンテキストのクエリ メソッドは、追加操作の適用に使用できる EntityQuery オブジェクトを返します。

ドメイン コンテキストからのすべてのクエリが非同期的に実行されます。クエリを実行するには、Load メソッドにパラメーターとして EntityQuery オブジェクトを渡します。

詳細については、「チュートリアル: ドメイン サービスのデータの取得と表示」を参照してください。

ドメイン サービスから顧客を取得する方法を次のコード例に示します。電話番号が 583 で始まる顧客にフィルターが適用され、LastName のアルファベット順に並べ替えられます。結果は DataGrid に表示されます。

Partial Public Class MainPage
    Inherits UserControl

    Private _customerContext As New CustomerDomainContext

    Public Sub New()
        InitializeComponent()

        Dim query As EntityQuery(Of Customer)

        query = _
            From c In Me._customerContext.GetCustomersQuery() _
            Where c.Phone.StartsWith("583") _
            Order By c.LastName

        Dim loadOp = Me._customerContext.Load(query)
        CustomerGrid.ItemsSource = loadOp.Entities
    End Sub

End Class
public partial class MainPage : UserControl
{
    private CustomerDomainContext _customerContext = new CustomerDomainContext();

    public MainPage()
    {
        InitializeComponent();
        EntityQuery<Customer> query = 
            from c in _customerContext.GetCustomersQuery()
            where c.Phone.StartsWith("583")
            orderby c.LastName
            select c;
        LoadOperation<Customer> loadOp = this._customerContext.Load(query);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }
}

データの変更

エンティティを更新、挿入、および削除するためのメソッドがドメイン サービスに含まれている場合、このようなメソッドはドメイン コンテキスト内に生成されません。代わりに、ドメイン コンテキストの SubmitChanges メソッドを使用すると、ドメイン サービスに対して適切な操作が呼び出されます。SubmitChanges を呼び出すまで、データ ソースの変更は行われません。保留中の変更は、RejectChanges メソッドを呼び出して取り消すことができます。

また、DomainContext クラスには、HasChanges プロパティと EntityContainer プロパティも用意されており、保留中の変更を評価できます。ドメイン コンテキストの EntityContainer オブジェクトによって、保留中の変更が追跡されます。呼び出し操作は呼び出されるとすぐに実行されるため、保留中の変更には、ドメイン サービス内の呼び出し操作への呼び出しは含まれていません。SubmitChanges を呼び出すと、保留中のすべての変更はまとめてドメイン サービスに送信されます。

新しいエンティティを追加するには、EntitySet オブジェクトの Add メソッドを呼び出すか、IEditableCollectionView オブジェクトの AddNew メソッドを呼び出します。AddNew メソッドを呼び出してエンティティを追加すると、追加したエンティティがコレクションにレンダリングされた後、その新しいエンティティがデータ ソースに保存されます。

詳細については、「チュートリアル: ドメイン サービスのデータの編集」を参照してください。

名前付き更新メソッド

ドメイン コンテキストには、ドメイン サービス上の名前付き更新メソッドごとに、パブリック アクセス修飾子が適用され IgnoreAttribute 属性でマークされていないメソッドが含まれます。ドメイン コンテキスト内に生成されるメソッドには、ドメイン サービスのメソッドと同じ名前が含まれます。クライアント プロジェクトで、メソッドを呼び出しますが、実際には SubmitChanges が呼び出されるまでこのメソッドは実行されません。EntityContainer は、名前付き更新メソッドへのすべての呼び出しを保留中の変更として追跡します。SubmitChanges を呼び出すと、メソッドは非同期的に処理されます。

名前付き更新メソッドでパラメーターとして渡されるエンティティに対して、クライアント プロジェクトにも同じ名前付き更新メソッドが生成されます。そのため、名前付き更新メソッドはドメイン コンテキストのインスタンスまたはエンティティのインスタンスを介して呼び出すことができます。生成されたコード ファイルを開くと、ドメイン コンテキスト内に生成されたメソッドによってエンティティに生成されたメソッドが呼び出されることがわかります。いずれの場合も、ドメイン コンテキストの SubmitChanges メソッドを呼び出して、メソッドを実行する必要があります。

エンティティの ResetPassword という名前付き更新メソッドを呼び出す方法の例を次に示します。OnSubmitCompleted は、データ操作の結果を処理するために実装するコールバック メソッドです。

selectedCustomer.ResetPassword()
customerContext.SubmitChanges(AddressOf OnSubmitCompleted, Nothing)
selectedCustomer.ResetPassword();
customerContext.SubmitChanges(OnSubmitCompleted, null);

呼び出し操作

ドメイン コンテキストには、ドメイン サービスの各呼び出し操作に使用するメソッドが含まれます。ドメイン操作とは異なり、呼び出し操作はすぐに実行されます。SubmitChanges メソッドは呼び出しません。呼び出し操作は非同期的に実行されます。呼び出し操作は InvokeOperation オブジェクトを返します。Value プロパティの値を取得して、サービス操作からの戻り値を取得します。

ほとんどのシナリオでは、データを読み込む際、呼び出し操作の代わりにクエリ操作を使用してください。クエリ メソッドは、単一の Entity オブジェクト、IQueryable<Entity> オブジェクト、または IEnumerable<Entity> オブジェクトを返します。クエリ メソッドは、中間層の DomainService およびクライアントの DomainContext によってサポートされるデータ パターンの整数部です。RIA Services フレームワークは、DomainService のクエリ メソッドから返されるこれらのエンティティに対してのみクライアント プロジェクト内にエンティティを生成します。

呼び出し操作では、エンティティ以外のデータを返して副作用を伴う操作を実行するための帯域外メカニズムを提供します。副作用の詳細については、HasSideEffects プロパティに関するトピックを参照してください。通常、呼び出し操作はクエリ メソッドには適していません。呼び出し操作でエンティティが返された場合でも、クエリ メソッドによって返された場合にのみ、クライアント プロジェクトにエンティティが生成されます。

GetLocalTemperature という呼び出し操作を使用する方法を次の例に示します。この例では、メソッドがエンティティ データとは無関係の値を取得することを前提としています。

Dim invokeOp As InvokeOperation(Of Integer)
invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, AddressOf OnInvokeCompleted, Nothing)

Private Sub OnInvokeCompleted(ByVal invOp As InvokeOperation(Of Integer))
  If (invOp.HasError) Then
    MessageBox.Show(String.Format("Method Failed: {0}", invOp.Error.Message))
    invOp.MarkErrorAsHandled()
  Else
    result = invOp.Value
  End If
End Sub
InvokeOperation<int> invokeOp = customerContext.GetLocalTemperature(selectedPostalCode, OnInvokeCompleted, null);

private void OnInvokeCompleted(InvokeOperation<int> invOp)
{
  if (invOp.HasError)
  {
    MessageBox.Show(string.Format("Method Failed: {0}", invOp.Error.Message));
    invOp.MarkErrorAsHandled();
  }
  else
  {
    result = invOp.Value;
  }
}

エラー処理

データを取得または変更する場合、これらの操作によって発生する可能性があるエラーを処理する方法を決定する必要があります。ドメイン コンテキストでデータを取得または変更するメソッドを呼び出すときは、エラーを処理するための手順を指定するパラメーターを含めます。データの読み込み時に、エラーを無視するように指定できます。データの変更時には、返される例外を処理する必要があります。詳細については、「クライアントでのエラー処理」を参照してください。