Verwalten des Datendienstkontextes (WCF Data Services)

Die DataServiceContext-Klasse kapselt Vorgänge, die für einen angegebenen Datendienst unterstützt werden. Im Gegensatz zu OData-Diensten ist der Kontext nicht zustandslos. Sie können daher mithilfe der DataServiceContext-Klasse den Zustand auf dem Client zwischen Interaktionen mit dem Datendienst beibehalten, um Funktionen wie das Änderungsmanagement zu unterstützen. Von dieser Klasse werden auch Identitäten verwaltet und Änderungen nachverfolgt.

Zusammenführungsoptionen und Identitätsauflösung

Wenn eine DataServiceQuery<TElement> ausgeführt wird, werden die Entitäten im Antwortfeed in Objekte materialisiert. Weitere Informationen finden Sie unter Objektmaterialisierung (WCF Data Services). Die Methode, mit der Einträge in einer Antwortnachricht in Objekte materialisiert werden, ist von der Identitätsauflösung und von der Zusammenführungsoption abhängig, mit der die Abfrage ausgeführt wurde. Wenn im Bereich eines einzelnen DataServiceContext verschiedene Abfragen oder Ladeanforderungen ausgeführt werden, verfolgt der WCF Data Services-Client nur eine einzelne Instanz eines Objekts, das über einen bestimmten Schlüsselwert verfügt. Dieser Schlüssel, der für das Ausführen einer Identitätsauflösung verwendet wird, identifiziert eine Entität eindeutig.

In der Standardeinstellung wird vom Client nur ein Eintrag im Antwortfeed in ein Objekt für Entitäten materialisiert, die noch nicht vom DataServiceContext verfolgt werden. Dies bedeutet, dass Änderungen an Objekten, die sich bereits im Cache befinden, nicht überschrieben werden. Dieses Verhalten wird gesteuert, indem für Abfragen und Ladevorgänge ein MergeOption-Wert angegeben wird. Diese Option wird festgelegt, indem die MergeOption-Eigenschaft auf dem DataServiceContext festgelegt wird. Der Standardwert der Zusammenführungsoption lautet AppendOnly. Mit dieser Einstellung werden nur Objekte für Entitäten materialisiert, die noch nicht verfolgt werden, d. h. vorhandene Objekte werden nicht überschrieben. Um zu verhindern, dass Änderungen an Objekten auf dem Client durch Aktualisierungen des Datendiensts überschrieben werden, kann auch die Option PreserveChanges festgelegt werden. Wenn OverwriteChanges festgelegt wird, werden Werte von Objekten des Clients durch die aktuellen Werte aus Einträgen im Antwortfeed ersetzt. Dies gilt auch, wenn an diesen Objekten bereits Änderungen vorgenommen wurden. Wenn eine NoTracking-Zusammenführungsoption verwendet wird, kann der DataServiceContext keine Änderungen, die an Clientobjekten gemacht wurden, an den Datendienst senden. Mit dieser Option werden Änderungen immer durch Werte des Datendiensts überschrieben.

Verwalten der Parallelität

OData unterstützt vollständige Parallelität, sodass der Datendienst Updatekonflikte erkennen kann. Der Datendienstanbieter kann so konfiguriert werden, dass der Datendienst mithilfe eines Parallelitätstokens nach Änderungen an Entitäten sucht. Dieses Token beinhaltet mindestens eine Eigenschaft eines Entitätstyps, die vom Datendienst überprüft wird, um zu bestimmen, ob sich eine Ressource geändert hat. Parallelitätstoken, die im eTag-Header von Antworten vom und Anforderungen an den Datendienst enthalten sind, werden vom WCF Data Services-Client verwaltet. Weitere Informationen finden Sie unter Aktualisieren des Datendiensts WCF Data Services.

Der DataServiceContext verfolgt Änderungen, die an Objekten vorgenommen wurden, die manuell mit AddObject, UpdateObject und DeleteObject oder von einer DataServiceCollection<T> gemeldet wurden. Wenn die SaveChanges-Methode aufgerufen wird, sendet der Client die Änderungen zurück an den Datendienst. SaveChanges kann fehlschlagen, wenn zwischen den Datenänderungen auf dem Client und den Änderungen im Datendienst ein Konflikt auftritt. In einem solchen Fall müssen Sie die Entitätsressource erneut abfragen, um die Updatedaten zu erhalten. Um Änderungen im Datendienst zu überschreiben, führen Sie die Abfrage mit der PreserveChanges-Zusammenführungsoption aus. Wenn Sie SaveChanges erneut aufrufen, werden die auf dem Client beibehaltenen Änderungen im Datendienst beibehalten, sofern an der Ressource im Datendienst noch keine anderen Änderungen vorgenommen wurden.

Speichern von Änderungen

Änderungen werden in der DataServiceContext-Instanz nachverfolgt, jedoch nicht unmittelbar an den Server gesendet. Wenn Sie die erforderlichen Änderungen für eine bestimmte Aktivität vorgenommen haben, rufen Sie SaveChanges auf, um alle Änderungen an den Datendienst zu übergeben. Ein DataServiceResponse-Objekt wird zurückgegeben, nachdem der SaveChanges-Vorgang abgeschlossen wurde. Das DataServiceResponse-Objekt enthält eine Folge von OperationResponse-Objekten, die wiederum eine Folge von EntityDescriptor-Instanzen oder LinkDescriptor-Instanzen enthalten, die die beibehaltenen Änderungen oder Änderungsversuche darstellen. Wenn eine Entität im Datendienst erstellt oder geändert wird, schließt der EntityDescriptor einen Verweis auf die aktualisierte Entität ein, der alle vom Server generierten Eigenschaftswerte enthält, z. B. den generierten ProductID-Wert im vorherigen Beispiel. Das .NET Framework-Objekt wird von der Clientbibliothek automatisch mit diesen neuen Werten aktualisiert.

Bei erfolgreichen Einfüge- und Aktualisierungsvorgängen wird die Zustandseigenschaft des EntityDescriptor- oder LinkDescriptor-Objekts, das dem Vorgang zugeordnet ist, auf Unchanged festgelegt, und die neuen Werte werden mithilfe von OverwriteChanges zusammengeführt.

Wenn im Datendienst ein Einfüge-, Aktualisierungs- oder Löschvorgang fehlschlägt, entspricht der Entitätszustand weiterhin dem Zustand vor dem Aufrufen von SaveChanges, und die Error-Eigenschaft der OperationResponse wird auf eine DataServiceRequestException festgelegt, die Informationen zum Fehler enthält. Weitere Informationen finden Sie unter Aktualisieren des Datendiensts WCF Data Services.

Verwalten von Anforderungen

Das OData-Protokoll bietet Flexibilität in Verhaltensweisen von Anforderungen zu und Antworten von einem Datendienst. Die Clientbibliothek ermöglicht es Ihnen, diese Flexibilität zu nutzen, indem Sie steuern, wie die Anwendung mit dem Datendienst interagiert.

Festlegen des Prefer-Headers für Änderungsvorgänge

Standardmäßig wird eine Nachrichtennutzlast nur als Reaktion auf eine POST-Anforderung zurückgegeben, um eine neue Entität zu erstellen. In diesem Fall wird die neue Entität in der Nutzlast zurückgegeben. Dies bedeutet, dass, wenn Updates an Objekten vorgenommen werden, die aktualisierte Entität nicht in der Nutzlast oder der Antwortnachricht zurückgegeben wird. Das OData-Protokoll gibt jedoch an, dass ein Client möglicherweise eine Änderung dieses Standardverhaltens mithilfe des Prefer-Headers anfordert. Der Prefer-Header in einer POST-, PUT-, PATCH- oder MERGE-Anforderung wird vom DataServiceContext auf Grundlage des Werts der DataServiceResponsePreference erstellt, der in der AddAndUpdateResponsePreference-Eigenschaft festgelegt wird. In der folgenden Tabelle werden die Prefer-Header-Optionen und die zugehörigen Antwortverhaltensweisen angezeigt:

Prefer-Header-Wert

AddAndUpdateResponsePreference-Wert

Antwortverhalten

Nicht in der Anforderung enthalten. Dies ist das Standardverhalten.

None

Eine Antwortnutzlast wird nur für POST-Anforderungen zurückgegeben und nicht für PUT-, PATCH- und MERGE-Anforderungen.

return-content

IncludeContent

Eine Antwortnutzlast wird für alle Änderungsanforderungen zurückgegeben.

return-no-content

NoContent

Keine Antwortnutzlast wird für alle Anforderungen zurückgegeben. Bei einer POST-Anforderung schließt der Datendienst auch einen DataServiceId-Header in die Antwort ein. Dieser Header wird verwendet, um den Schlüsselwert der neu erstellten Entität zu übermitteln.

Hinweis

Selbst wenn der Datendienst eine Version des OData-Protokolls unterstützt, das den Prefer-Header unterstützt, kann ein Datendienst wählen, diese Arten von Anforderungsverarbeitungseinstellungen nicht zu beachten.

Festlegen der HTTP-Methode für Updates

Die .NET Framework-Clientbibliothek sendet Updates an vorhandenen Entitäten standardmäßig als MERGE-Anforderungen. Durch eine MERGE-Anforderung in OData werden ausgewählte Eigenschaften der Entität aktualisiert. Der Client schließt jedoch immer alle Eigenschaften in die MERGE-Anforderung ein, auch Eigenschaften, die nicht geändert wurden. Das OData-Protokoll unterstützt auch das Senden von PUT- und PATCH-Anforderungen zum Aktualisieren von Entitäten. In einer PUT-Anforderung wird eine vorhandene Entität im Grunde durch eine neue Instanz der Entität mit Eigenschaftswerten vom Client ersetzt. PATCH-Anforderungen werden auf die gleiche Weise wie MERGE-Anforderungen behandelt; PATCH ist jedoch eine Standard-HTTP-Aktion, wohingegen MERGE von OData definiert wird. Dieses Updateverhalten wird entweder durch Bereitstellen des ReplaceOnUpdate-Werts zum Verwenden von PUT-Anforderungen, oder durch den PatchOnUpdate-Wert zum Verwenden von PATCH-Anforderungen als Optionen beim Aufrufen von SaveChanges(SaveChangesOptions) festgelegt.

Hinweis

Eine PUT-Anforderung verhält sich anders als eine MERGE- oder PATCH-Anforderung, wenn der Client nicht alle Eigenschaften der Entität kennt.Dies kann vorkommen, wenn ein Entitätstyp in einen neuen Typ auf dem Client projiziert wird.Diese Situation kann auch auftreten, wenn der Entität im Datenmodell des Diensts neue Eigenschaften hinzugefügt wurden und die IgnoreMissingProperties-Eigenschaft des DataServiceContext auf true festgelegt ist, um solche Clientzuordnungsfehler zu ignorieren.In diesen Fällen werden bei einer PUT-Anforderung alle Eigenschaften, die dem Client nicht bekannt sind, auf die Standardwerte zurückgesetzt.

POST-Tunneln

Standardmäßig sendet die Clientbibliothek Anforderungen zum Erstellen, Lesen, Aktualisieren und Löschen an einen OData-Dienst, indem die entsprechenden HTTP-Methoden von POST, GET, PUT/MERGE/PATCH und DELETE verwendet werden. Dies erhält die grundlegenden Prinzipien von Representational State Transfer (REST) aufrecht. Nicht jede Webserverimplementierung unterstützt jedoch den vollständigen Satz von HTTP-Methoden. In einigen Fällen könnten die unterstützten Methoden nur auf GET und POST beschränkt sein. Dies kann geschehen, wenn ein Vermittler, wie beispielsweise eine Firewall, Anforderungen mit bestimmten Methoden blockiert. Da die GET-Methode und die POST-Methode am häufigsten unterstützt werden, schreibt OData eine Möglichkeit vor, mit einer POST-Anforderung nicht unterstützte HTTP-Methoden auszuführen. Bekannt als Methodentunneln oder POST-Tunneln ermöglicht dies einem Client, eine POST-Anforderung mit der tatsächlichen im benutzerdefinierten X-HTTP-Method-Header angegebenen Methode zu senden. Um POST-Tunneln für Anforderungen zu aktivieren, legen Sie die UsePostTunneling-Eigenschaft auf der DataServiceContext-Instanz auf true fest.

Auflösen des Basis-URI von Entitätenmengen

Standardmäßig geht der Client davon aus, dass der gleiche Basis-URI für alle Entitätenmengen freigegeben ist, die auch als Auflistungen bezeichnet werden. Dieser Basis-URI wird von der BaseUri-Eigenschaft im DataServiceContext definiert. Das OData-Protokoll lässt aber zu, dass ein Datendienst Entitätenmengen als Feeds, die über andere Basis-URIs verfügen, verfügbar macht. Um in der Lage zu sein, Entitätenmengen mit anderen Basis-URIs zu verwenden, ermöglicht der Client es Ihnen, einen Delegaten beim DataServiceContext zu registrieren, der verwendet werden kann, um die Basis-URIs verschiedener Entitätenmengen aufzulösen. Dieser Delegat ist eine Methode, die eine Zeichenfolge (der Entitätenmengenname) verwendet und einen Uri (der Basis-URI für die angegebene Entitätenmenge) zurückgibt. Dieser Resolver wird von Zuweisung zur ResolveEntitySet-Eigenschaft beim DataServiceContext registriert. Eine Resolverimplementierung kann bei erstelltem Kontext die Informationen zu Auflistungen lesen, die vom Datendienststamm zurückgegeben werden, sowie die Basis-URI-Werte für jede Auflistung in einem Wörterbuch speichern. Dieses Wörterbuch könnte dann vom Resolver verwendet werden, um den URI für eine bestimmte Entitätenmenge zurückzugeben. Ein vollständigeres Beispiel, einschließlich des Beispielcodes, finden Sie im Beitrag Entitätenmengenresolver.

Versionsanforderungen

Die DataServiceContext-Verhaltensweisen haben die folgenden Anforderungen an die OData-Protokollversion:

  • Die Unterstützung für den Prefer-Header und die PATCH-Anforderungen erfordern, dass sowohl der Client als auch der Datendienst Version 3.0 des OData-Protokolls und höhere Versionen unterstützen.

  • Die Unterstützung für Entitätenmengenresolver erfordert die Version der WCF Data Services-Clientbibliothek, die in der Data Framework-Version oder einer höheren Version enthalten ist.

Weitere Informationen finden Sie unter Datendienst-Versionskontrolle (WCF Data Services).