DomainContext und Vorgänge

In diesem Thema wird beschrieben, wie ein Client einer WCF RIA Services-Anwendung mithilfe des Domänenkontexts mit dem Domänendienst in der Anwendung der mittleren Ebene kommuniziert. Es findet keine direkte Interaktion mit den Domänendiensten vom Clientprojekt aus statt. Stattdessen wird im Clientprojekt für jeden Domänendienst im Serverprojekt eine Domänenkontextklasse generiert. Sie rufen Methoden für die Domänenkontextklasse auf, die der Domänendienstmethode entspricht, die Sie verwenden möchten. Die generierte Domänenkontextklasse leitet sich von der DomainContext-Klasse ab. Standardmäßig wird der Domänenkontext mit einem Postfix von Context anstelle des Postfixes von Service benannt, das für die Benennung des Domänendiensts verwendet wird. Ein Domänendienst mit dem Namen HRService besitzt z. B. einen entsprechenden Domänenkontext mit dem Namen HRContext. Informationen zum Definieren von Domänendienstmethoden finden Sie unter Domänendienste.

Der generierte Domänenkontext enthält drei Konstruktormethoden:

  1. einen Standardkonstruktor, der den URI für die Kommunikation mit dem Domänendienst über HTTP einbettet.

  2. einen Konstruktor, mit dem ein alternativer URI angegeben werden kann.

  3. einen Konstruktor, mit dem Sie eine benutzerdefinierte DomainClient-Implementierung bereitstellen können. Dieser Konstruktor wird in der Regel für Komponententests oder zum Umleiten zu einer benutzerdefinierten Transportschicht verwendet.

Die DomainContext-Klasse unterstützt Vorgänge zum Abfragen, Senden und Aufrufen von Domänen. Für jeden Vorgangstyp gibt es eine entsprechende Klasse, die den aktiven asynchronen Vorgang darstellt. Dabei handelt es sich um folgende Klassen: LoadOperation, SubmitOperation und InvokeOperation.

Ein EntitySet-Objekt wird im Domänenkontext mit Eigenschaften generiert, die angeben, welche Vorgänge (Einfügen, Aktualisieren oder Löschen) vom Client gestattet werden.

Abfragen

Die Abfragemethode im Domänenkontext trägt üblicherweise den gleichen Namen wie die Methode für die Domänendienstabfrage sowie ein Postfix von Query. Eine GetCustomersQuery-Methode im Domänenkontext wird z. B. von einer GetCustomers-Methode im Domänendienst generiert. Die Methode für die Domänenkontextabfrage gibt ein EntityQuery-Objekt zurück, mit dem Sie zusätzliche Vorgänge übernehmen können.

Alle Abfragen von einem Domänenkontext werden asynchron ausgeführt. Um die Abfrage auszuführen, übergeben Sie das EntityQuery-Objekt als Parameter in der Load-Methode.

Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Abrufen und Anzeigen von Daten aus einem Domänendienst.

Der folgende Code zeigt, wie Kunden aus dem Domänendienst abgerufen werden. In diesem Beispiel werden Kunden herausgefiltert, deren Telefonnummern mit 583 beginnen, und alphabetisch nach "LastName" sortiert. Die Ergebnisse werden in einem DataGrid angezeigt.

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;
    }
}

Ändern von Daten

Wenn der Domänendienst Methoden zum Aktualisieren, Einfügen und Löschen von Entitäten einschließt, werden diese Methoden nicht im Domänenkontext generiert. Stattdessen verwenden Sie im Domänenkontext die SubmitChanges-Methode. Infolgedessen werden die richtigen Vorgänge im Domänendienst aufgerufen. In der Datenquelle werden erst Änderungen vorgenommen, wenn SubmitChanges aufgerufen wird. Sie können ausstehende Änderungen abbrechen, indem Sie die RejectChanges-Methode aufrufen.

Die DomainContext-Klasse stellt auch die HasChanges-Eigenschaft und die EntityContainer-Eigenschaft bereit, um die Auswertung ausstehender Änderungen zu ermöglichen. Das EntityContainer-Objekt für einen Domänenkontext verfolgt die ausstehenden Änderungen nach. Ausstehende Änderungen schließen keine Aufrufe für Startvorgänge im Domänendienst ein, da Startvorgänge umgehend bei ihrem Aufruf ausgeführt werden. Wenn Sie SubmitChanges aufrufen, werden alle ausstehenden Änderungen zusammen an den Domänendienst gesendet.

Sie können eine neue Entität hinzufügen, indem Sie entweder die Add-Methode für das EntitySet-Objekt oder die AddNew-Methode für das IEditableCollectionView-Objekt aufrufen. Wenn Sie eine Entität hinzufügen, indem Sie die AddNew-Methode aufrufen, wird diese Entität in der Auflistung gerendert, bevor die neue Entität in der Datenquelle gespeichert wird.

Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Bearbeiten von Daten von einem Domänendienst.

Benannte Updatemethoden

Der Domänenkontext enthält eine Methode für jede benannte Updatemethode auf dem Domänendienst, der einen öffentlichen Zugriffsmodifizierer besitzt und nicht mit dem IgnoreAttribute-Attribut markiert wird. Die generierte Methode im Domänenkontext enthält den gleichen Namen wie die Methode auf dem Domänendienst. Im Clientprojekt rufen Sie die Methode auf, doch die Methode wird eigentlich erst ausgeführt, wenn SubmitChanges aufgerufen wird. EntityContainer verfolgt alle Aufrufe von benannten Updatemethoden als ausstehende Änderungen nach. Wenn Sie SubmitChanges aufrufen, wird die Methode asynchron verarbeitet.

Die gleiche benannte Updatemethode wird auch im Clientprojekt für die Entität generiert, die als Parameter in der benannten Updatemethode übergeben wird. Daher kann die benannte Updatemethode entweder über eine Instanz des Domänenkontexts oder eine Instanz der Entität aufgerufen werden. Wenn Sie die generierte Codedatei öffnen, stellen Sie fest, dass die generierte Methode im Domänenkontext lediglich die generierte Methode in der Entität aufruft. In jedem Fall müssen Sie nach wie vor die SubmitChanges-Methode für den Domänenkontext aufrufen, um die Methode auszuführen.

Im folgenden Beispiel wird gezeigt, wie eine benannte Updatemethode mit dem Namen ResetPassword für die Entität aufgerufen wird. OnSubmitCompleted ist eine Rückrufmethode, die Sie implementieren, um die Ergebnisse des Datenvorgangs zu bearbeiten.

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

Startvorgänge

Der Domänenkontext enthält eine Methode für jeden Startvorgang im Domänendienst. Im Gegensatz zu Domänenvorgängen werden Startvorgänge sofort ausgeführt. Die SubmitChanges-Methode wird nicht aufgerufen. Startvorgänge werden asynchron ausgeführt. Der Startvorgang gibt ein InvokeOperation-Objekt zurück. Sie rufen den Wert der Value-Eigenschaft ab, um den zurückgegebenen Wert aus dem Dienstvorgang abzurufen.

In fast allen Szenarien sollten Sie zum Laden von Daten statt Startvorgängen Abfragevorgänge verwenden. Abfragemethoden geben entweder ein einzelnes Entity-Objekt, ein IQueryable<Entity>-Objekt oder ein IEnumerable<Entity>-Objekt zurück. Abfragemethoden sind ein wesentlicher Bestandteil des Datenmusters, das von DomainService auf der mittleren Ebene und von DomainContext auf dem Client unterstützt wird. Das RIA Services-Framework generiert Entitäten im Clientprojekt nur für die Entitäten, die von Abfragemethoden in einem DomainService zurückgegeben werden.

Startvorgänge stellen einen Out-of-Band-Mechanismus für die Rückgabe von nicht entitätsbezogenen Daten und die Ausführung von Vorgängen mit Nebeneffekten bereit. Weitere Informationen zu Nebenwirkungen finden Sie in der HasSideEffects-Eigenschaft. Startvorgänge sind normalerweise nicht für Abfragemethoden geeignet. Selbst wenn ein Startvorgang eine Entität zurückgibt, wird die Entität nur dann für das Clientprojekt generiert, wenn sie von einer Abfragemethode zurückgegeben wird.

Im folgenden Beispiel wird gezeigt, wie ein Startvorgang mit dem Namen GetLocalTemperature verwendet wird. Für dieses Beispiel wird angenommen, dass die Methode einen Wert abruft, der sich nicht auf Entitätsdaten bezieht.

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;
  }
}

Behandeln von Fehlern

Wenn Sie Daten abrufen oder ändern, müssen Sie festlegen, wie aus diesen Vorgängen resultierende Fehler behandelt werden sollen. Wenn Sie Methoden im Domänenkontext aufrufen, mit denen Daten abgerufen oder geändert werden, schließen Sie Parameter ein, die die Schritte zur Behandlung von Fehlern angeben. Wenn Sie Daten laden, können Sie angeben, dass Fehler ignoriert werden. Wenn Sie Daten ändern, müssen Sie die Ausnahme behandeln, die zurückgegeben wird. Weitere Informationen finden Sie unter Fehlerbehandlung auf dem Client.