Freigeben über


Einen Datensatz mit Upsert erstellen oder aktualisieren

Sie können die Komplexität verringern, die in Datenintegrationsszenarien involviert ist, indem Sie die Nachricht Upsert verwenden. Wenn Sie Daten von einem externen System in Microsoft Dataverse laden, beispielsweise in einem Massendaten-Integrationsszenario, wissen Sie möglicherweise nicht, ob ein Datensatz bereits in Dataverse vorhanden ist. In solchen Fällen können Sie nicht wissen, ob Sie die Update- oder Create-Nachricht verwenden sollten. Sie müssen den Datensatzes zuerst abrufen, um zu bestimmen, ob er vorhanden ist, bevor der entsprechende Vorgang ausgeführt wird. Sie können diese Komplexität durch Verwendung der Upsert-Nachricht jetzt reduzieren und Daten effizienter in Dataverse laden.

Es gibt Leistungseinbußen beim Verwenden von Upsert im Vergleich zum Verwenden von Create. Wenn Sie sicher sind, dass der Datensatz nicht vorhanden ist, verwenden Sie Create.

Anmerkung

Während Sie Primärschlüsselwerte mit Upsert verwenden können, wird im Allgemeinen erwartet, dass Sie alternative Schlüssel verwenden, da der übliche Anwendungsfall Datenintegrationsszenarien sind. Weitere Informationen: Einen lternativschlüssel verwenden, um auf einen Datensatz zu verweisen

Upsert für eine elastische Tabelle

Das Verhalten elastischer Tabellen für Upsert unterscheidet sich von Standardtabellen. Bei elastischen Tabellen ruft der Upsert-Vorgang nicht die Create- oder Update-Nachricht auf, je nachdem, ob der Datensatz bereits vorhanden ist oder nicht. Upsert wendet die Änderungen direkt in der Entität an.

  • Wenn der Datensatz vorhanden ist: Alle Daten im Datensatz werden durch die Daten in der Entität überschrieben. Es gibt kein Update-Ereignis.
  • Wenn der Datensatz nicht vorhanden ist: Es wird ein neuer Datensatz erstellt. Es gibt kein Create-Ereignis.

Dies hat Auswirkungen darauf, wo Sie Geschäftslogik für Ereignisse anwenden. Ein neuer Datensatz kann entweder mit Create oder Upsert erstellt werden. Ein Datensatz kann entweder mit Update oder Upsert aktualisiert werden. Wenn Sie Logik konsistent für Create oder Update in elastischen Tabellen anwenden müssen, müssen Sie diese Logik auch in Upsert einschließen. Weitere Informationen: Upsert-Prozess für einen Datensatz in einer elastischen Tabelle

Den Upsert-Prozess für Standardtabellen verstehen

Upsert-Nachrichten werden auf dem Server verarbeitet. Das SDK für .NET-Klassen verwendet dieselben Objekte, die auf dem Server verwendet werden. Daher wird in der folgenden Erklärung das SDK für .NET-Klassen verwendet, um zu beschreiben, wie eine UpsertRequest-Instanz verarbeitet und die UpsertResponse-Instanz zurückgegeben wird.

In den folgenden Schritten wird die Verarbeitungslogik auf dem Server bei Erhalt von UpsertRequest für eine Standardtabelle beschrieben:

  1. Für die UpsertRequest-Instanz ist die Zieleigenschaft standardmäßig mit einer Entity-Instanz festgelegt, die die Daten für einen Create- oder Update-Vorgang enthält.
    • Für die Entity Instanz ist in der Regel die Entity.KeyAttributes-Eigenschaft mit Werten festgelegt, die zum Identifizieren des Datensatzes mithilfe von Alternativschlüsseln verwendet werden.
  2. Sofern vorhanden, versucht Dataverse, den Datensatz mithilfe der Eigenschaft Entity.Id der Entity-Instanz zu finden, die auf die Eigenschaft Target festgelegt ist. Andernfalls werden die alternativen Schlüsselwerte aus der Entity.KeyAttributes-Eigenschaft verwendet.
  3. Wenn der Datensatz vorhanden ist:
    1. Legen Sie die TargetEntity.Id mit dem Wert des Primärschlüssels des gefundenen Datensatzes fest.
    2. Entfernen Sie alle Daten aus der TargetEntity.Attributes-Auflistung , die dieselben Schlüssel verwenden, die in der TargetEntity.KeyAttributes-Auflistung verwendet werden.
    3. Rufen Sie Update auf.
    4. Legen Sie die UpsertResponse.RecordCreated-Eigenschaft auf false fest.
    5. Erstellen Sie eine EntityReference aus der Target-Entität als Wert für UpsertResponse.Target.
    6. Geben Sie den UpsertResponse zurück.
  4. Wenn der Datensatz nicht vorhanden ist:
    1. Kopieren Sie alle Daten von TargetEntity.KeyAttributes, das Target noch nicht in seiner Entity.Attributes-Sammlung hat, in TargetEntity.Attributes.
    2. Rufen Sie Create auf.
    3. Legen Sie UpsertResponse.RecordCreated auf true fest.
    4. Erstellen Sie eine EntityReference aus der Target-Entität und dem id-Ergebnis des Create-Vorgangs als Wert für UpsertResponse.Target.
    5. Geben Sie den UpsertResponse zurück.

Das folgende Diagramm zeigt den Prozess auf dem Server wenn ein UpsertRequest empfangen wird.

Upsert-Prozessfluss

Anleitung zum Verfassen von Anfragen

Bei der Verwendung von Alternativschlüsseln zum Identifizieren eines Datensatzes wird die Einbeziehung der Alternativschlüssel-Daten in den Teil der Anforderung, der die zu speichernden Daten darstellt, nicht empfohlen oder ist nicht erforderlich.

Wenn Sie die Web-API verwenden und mit dem SDK für .NET nicht vertraut sind, ist der oben beschriebene serverseitige Prozess möglicherweise schwer nachvollziehbar. Die Web-API hat nicht das gleiche Objektmodell wie die SDK-Objekte, die in der obigen Beschreibung und dem Diagramm genutzt werden, aber die Daten können wie in der folgenden Tabelle gezeigt zugeordnet werden.

Internet-API SDK Eigenschaft
Schlüsselwerte in URL Entity.KeyAttributes-Eigenschaft Enthält die Alternativschlüssel-Daten zur Identifizierung des Datensatzes.
Text der Anforderung Die Entity ist auf die UpsertRequest.Target-Eigenschaft festgelegt. Enthält die zu verwendenden Daten für Create oder Update.

Obwohl diese Anfragen wie oben beschrieben auf dem Server verarbeitet werden, kann man sich das so vorstellen:

  • Wenn der Datensatz vorhanden ist: Die im Hauptteil der Anforderung festgelegten Daten für diese Alternativschlüssel-Werte in der URL werden entfernt, es ergibt also keinen Sinn, sie einzubeziehen. Durch diese Vorgehensweise wird sichergestellt, dass Sie die Alternativschlüssel-Werte eines Datensatzes nicht aktualisieren können, wenn Sie diese Alternativschlüssel-Werte zur Identifizierung verwenden. Sie können Alternativschlüssel-Werte mit dem Primärschlüssel oder einem anderen Satz von Alternativschlüsseln ändern.
  • Wenn der Datensatz nicht vorhanden ist: Alle im Hauptteil der Anforderung festgelegten Alternativschlüssel-Werte werden zum Erstellen des neuen Datensatzes verwendet, auch wenn die Daten anders sind als die durch die Alternativschlüssel in der URL angegebenen Werte. Wenn im Hauptteil der Anforderung keine Alternativschlüssel-Daten vorhanden sind, werden die Alternativschlüssel-Daten aus der URL in den Hauptteil der Anfrage kopiert. Um eine Situation zu vermeiden, in der die Schlüsselwerte in der URL und die entsprechenden Schlüsselwerte im Textkörper nicht übereinstimmen, ist es am besten, sie überhaupt nicht in den Textkörper aufzunehmen.

Verwenden von Web-API

Bei der Web-API werden die Upsert- und Update-Nachrichten beide mit http PATCH initiiert gegen eine bestimmte EntitySet-Ressource, die durch die Schlüssel in der URL identifiziert wird.

Der Unterschied zwischen Upsert und Update wird dadurch definiert, ob die If-Match: * Anforderungsheader enthalten ist. Wenn der If-Match: *-Anforderungsheader enthalten ist und keine Ressource mit den Schlüsselwerten in der URL übereinstimmt, gibt die Anforderung einen 404 Not Found-Statuscode zurück. Der If-Match: *-Anforderungsheader stellt sicher, dass die PATCH-Anfrage einUpdate-Vorgang ist.

Wenn der If-Match: *-Anforderungsheader nicht enthalten isst, wird die PATCH-Anforderung wie eine Upsert behandelt und ein neuer Datensatz wird erstellt, wenn keine Datensätze gefunden werden, die den Schlüsseln in der URL entsprechen. Im Gegensatz zum SDK erfahren Sie in der Antwort jedoch nicht, ob ein Datensatz erstellt wurde. Die Statusantwort ist 204 No Content in jedem Fall.

Wenn Sie einen Prefer: return=representation-Anforderungsheader einschließen, gibt das System einen 201 Created-Status für Create und einen 200 OK-Status für Update zurück. Durch das Hinzufügen dieses Headers wird ein zusätzlicher Retrieve-Vorgang hinzugefügt, es wirkt sich also auf die Leistung aus. Wenn Sie diese Option verwenden, stellen Sie sicher, dass die $select-Abfrageoption, die Sie hinzufügen, nur den Primärschlüsselwert enthält. Weitere Informationen:

Mit einer PATCH-Anforderung können Sie auch den If-None-Match: *-Anforderungsheader zum Blockieren eines Update erfassen, wenn Sie nur Datensätze erstellen möchten. Weitere Informationen: upsert-Vorgänge begrenzen.

Web-API-Beispielcode

Die folgenden Beispiele zeigen Upsert-Vorgänge, die eine Tabelle mit zwei Alternativschlüssel-Spalten verwenden:

Erstellen Sie mit Upsert

Diese Anfrage erstellt einen Datensatz.

Anforderung:

PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2) HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/json

{ "example_name": "2:2" }

Antwort:

HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2)

Aktualisieren Sie mit Upsert

Diese Anforderung aktualisiert den durch die obige Anforderung erstellten Datensatz.

Anforderung:

PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2) HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: application/json

{ "example_name": "2:2 Updated" }

Antwort:

HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization Uri]/api/data/v9.2/example_records(example_key1=2,example_key2=2)

Anmerkung

Die Antwort ist für Create- oder Update-Vorgänge identisch.

Mit „Upsert“ und der Einstellung „return=representation“ erstellen

Wenn Sie den Prefer: return=representation-Header verwenden, können Sie einen anderen Statuscode in der Antwort erhalten, um anzugeben, ob der Datensatz erstellt oder aktualisiert wurde.

Die folgende Anforderung erstellt einen neuen Datensatz und gibt den Status 201 Created zurück.

Anforderung:

PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=3,example_key2=3)?$select=example_recordid HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Prefer: return=representation
Content-Type: application/json

{ "example_name": "3:3" }

Antwort:

HTTP/1.1 201 Created
Content-Type: application/json; odata.metadata=minimal
ETag: W/"71004878"
Preference-Applied: return=representation
OData-Version: 4.0

{
  "@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#example_records(example_recordid)/$entity",
  "@odata.etag": "W/\"71004878\"",
  "example_recordid": "ef0d112e-d70e-ed11-82e5-00224822577b"
}

Aktualisieren Sie mit Upsert und Präferenz return=representation

Diese Anforderung aktualisiert den durch die obige Anforderung erstellten Datensatz und gibt den Status 200 OK zurück, um zu zeigen, dass es sich um einen Aktualisierungsvorgang handelte.

Anforderung:

PATCH [Organization Uri]/api/data/v9.2/example_records(example_key1=3,example_key2=3)?$select=example_recordid HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Prefer: return=representation
Content-Type: application/json

{ "example_name": "3:3 Updated" }

Antwort:

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal
ETag: W/"71004880"
OData-Version: 4.0

{
  "@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#example_records(example_recordid)/$entity",
  "@odata.etag": "W/\"71004880\"",
  "example_recordid": "ef0d112e-d70e-ed11-82e5-00224822577b"
}

Verwenden des SDK für .NET

Die Clientanwendung verwendet die IOrganizationService.Execute-Methode mit einer UpsertRequest-Instanz, für die die Target-Eigenschaft mit einer Entity-Instanz festgelegt ist, die die Daten für einen Create- oder Update-Vorgang enthält. Für die Entity Instanz ist in der Regel die Entity.KeyAttributes-Eigenschaft mit Werten festgelegt, die zum Identifizieren des Datensatzes mithilfe von Alternativschlüsseln verwendet werden.

Die UpsertResponse.RecordCreated-Eigenschaft gibt an, ob der Datensatz erstellt wurde, und UpsertResponse.Target enthält einen Verweis auf den Datensatz, der erstellt oder aktualisiert wurde.

SDK für .NET-Beispielcode

Die Datei SampleMethod.cs im Beispiel Einen Datensatz mit Upsert einfügen oder aktualisieren enthält die folgende ProcessUpsert-Methode, um die UpsertRequest-Meldung auf den Inhalt einer XML-Datei anzuwenden, um neue Datensätze zu erstellen oder vorhandene zu aktualisieren.

public static void ProcessUpsert(CrmServiceClient service, String Filename)
{
    Console.WriteLine("Executing upsert operation.....");
    XmlTextReader tr = new XmlTextReader(Filename);
    XmlDocument xdoc = new XmlDocument();
    xdoc.Load(tr);
    XmlNodeList xnlNodes = xdoc.DocumentElement.SelectNodes("/products/product");

    foreach (XmlNode xndNode in xnlNodes)
    {
        String productCode = xndNode.SelectSingleNode("Code").InnerText;
        String productName = xndNode.SelectSingleNode("Name").InnerText;
        String productCategory = xndNode.SelectSingleNode("Category").InnerText;
        String productMake = xndNode.SelectSingleNode("Make").InnerText;

        //use alternate key for product
        Entity productToCreate = new Entity("sample_product", "sample_productcode", productCode);

        productToCreate["sample_name"] = productName;
        productToCreate["sample_category"] = productCategory;
        productToCreate["sample_make"] = productMake;
        var request = new UpsertRequest()
        {
            Target = productToCreate
        };

        try
        {
            // Execute UpsertRequest and obtain UpsertResponse.
            var response = (UpsertResponse)service.Execute(request);
            if (response.RecordCreated)
                Console.WriteLine("New record {0} is created!", productName);
            else
                Console.WriteLine("Existing record {0} is updated!", productName);
        }

        // Catch any service fault exceptions that Dataverse throws.
        catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
        {
            throw;
        }
    }
}

Siehe auch

Synchronisieren von Daten mit externen Systemen mithilfe der Änderungsnachverfolgung
Definierter alternative Schlüssel für eine Tabelle
Verwenden Sie einen Alternativschlüssel, um auf einen Datensatz zu verweisen