Aktualisieren und Löschen von Tabellenzeilen über die SDK für .NET
Dieseser Artikel enthält Beispiele zu später und früherer gebundenen Programmierungsstilen. Weitere Informationen: Programmierung mit später und früher Bindung mithilfe des SDK für .NET
Jedes der Beispiele verwendet eine svc
-Variable, die eine Instanz einer Klasse darstellt, die Sie auf IOrganizationService der Benutzeroberfläche implementieren. Weitere Informationen zu Klassen finden Sie unter Organisationsservice-Benutzeroberfläche.
Wichtig
Beziehen Sie beim Aktualisieren einer Tabellenzeile nur die Spalten ein, die Sie ändern. Durch einfaches Aktualisieren der Spalten einer zuvor abgerufenen Tabellenzeile wird jede Spalte aktualisiert, auch wenn der Wert unverändert ist. Dies kann Systemereignisse verursachen, die Geschäftslogik starten können, da angenommen wird, dass die Werte geändert haben. Dies kann auch dazu führen, dass Spalten in Überwachungsdaten scheinbar aktualisiert wurden, obwohl sie sich tatsächlich nicht geändert haben.
Sie sollten eine neue Entity
-Instanz erstellen, das ID-Attribut und alle Attributwerte festlegen, die Sie ändern, und diese Entitätsinstanz zur Aktualisierung der Tabellenzeile verwenden.
Anmerkung
Die Spaltendefinition enthält eine Eigenschaft RequiredLevel
. Wenn diese auf SystemRequired
festgelegt ist, können Sie diese Spalten nicht auf einen Nullwert setzen. Wenn Sie dies versuchen, erhalten Sie den Fehlercode -2147220989
mit der Meldung Attribute: <attribute name> cannot be set to NULL
.
Weitere Informationen: Erforderlichkeitsstufe für Spalten (Attribut)
Grundlegende Aktualisierung
In den beiden folgenden Beispielen wird die IOrganizationService.Update-Methode verwendet, um Spaltenwerte für eine zuvor abgerufene Tabellenzeile festzulegen.
Nutzen Sie die Entity.Id-Eigenschaft, um den eindeutigen Bezeichnerwert der abgerufenen Zeile der Entitätsinstanz zu übertragen, die verwendet wird, um den Vorgang zu aktualisieren.
Anmerkung
Wenn Sie versuchen, eine Zeile ohne Primärschlüsselwert zu aktualisieren, erhalten Sie folgende Fehlermeldung: Entity Id must be specified for Update
.
Wenn Sie keinen Primärschlüsselwert haben, können Sie Zeilen auch mit Alternativschlüsseln aktualisieren. Weitere Informationen: Update mit Alternativschlüssel
Das folgende Bespiel zeigt, wie mit der Entitätsklasse ein Konto anhand der IOrganizationService.Update-Methode erstellt wird.
var retrievedAccount = new Entity("account", new Guid("a976763a-ba1c-e811-a954-000d3af451d6"));
//Use Entity class with entity logical name
var account = new Entity("account");
account.Id = retrievedAccount.Id;
// set attribute values
// Boolean (Two option)
account["creditonhold"] = true;
// DateTime
account["lastonholdtime"] = DateTime.Now;
// Double
account["address1_latitude"] = 47.642311;
account["address1_longitude"] = -122.136841;
// Int
account["numberofemployees"] = 400;
// Money
account["revenue"] = new Money(new Decimal(2000000.00));
// Picklist (Option set)
account["accountcategorycode"] = new OptionSetValue(2); //Standard customer
//Update the account
svc.Update(account);
Die UpdateRequest-Klasse
Anstatt die IOrganizationService.Update-Methode zu nutzen, können Sie entweder die späte Entitätsklassen oder die früh gebundenen Entitätsklassen mit der UpdateRequest-Klasse nutzen, indem Sie die Entitätsinstanz auf UpdateRequest.Target-Eigenschaft festlegen und dann die IOrganizationService.Execute-Methode nutzen, um ein Beispiel zu erhalten.
Anmerkung
Die UpdateResponse-Klasse weiste keine Eigenschaften auf. Während sie mit der IOrganizationService.Execute-Methode zurückgegeben wird, ist es nicht nötig, darauf zu referenzieren.
var request = new UpdateRequest()
{ Target = account };
svc.Execute(request);
Wedd ie UpdateRequest-Klasse verwendet werden soll
Sie müssen die UpdateRequest-Klasse verwenden, wenn Sie optionale Parameter behalten möchten. Es gibt zwei Fälle, in denen Sie möglicherweise bestimmte Parameter brauchen.
- Geben Sie den Zeitpunkt an, zu dem der Duplikaterkennungsauftrag gestartet werden soll. Weitere Informationen: Erkennen von doppelten Daten mit dem SDK für .NET
- Wenn Sie eine Tabellenzeile erstellen, die eine Lösungskomponente darstellt, z. B. eine WebResource, und sie mit einer bestimmten Lösung verknüpfen möchten. In diesem Fall überprüfen Sie den Wert der mithilfe Solution.UniqueName des Parameters
SolutionUniqueName
einschließen möchten. Weitere Informationen: Nachrichten mit dem SDK für .NET verwenden
Sie müssen die verwenden Klasse auch UpdateRequest nutzen, wenn Sie einem Verhalten eine optimistische Parallelität angeben möchten. Weitere Informationen: Verhalten der optimistischen Parallelität
UpdateMultipleRequest-Klasse verwenden
Die UpdateMultipleRequest-Klasse ist die leistungsstärkste Möglichkeit, mehrere Datensätze in einer einzelnen Anforderung zu aktualisieren. Weitere Informationen: Nachrichten zu Massenvorgängen
Updaten verknüpfter Entitäten in einem Vorgang
Auf ähnliche Weise, wie Sie verknüpfte Tabellenzeilen in einem Vorgang erstellen können, können Sie zugehörige Tabellenzeilen auch aktualisieren.
Um die zugehörigen Tabellenzeilen zu aktualisieren, müssen Sie eine Zeile mit den zugehörigen Zeilen abrufen, damit Sie auf die ID-Werte zugreifen können. Weitere Informationen: Abrufen mit Bezugszeilen
Wichtig
Zeilen werden in einer bestimmten Reihenfolge aktualisiert. Zuerst werden primäre Tabellenzeilen verarbeitet und dann verknüpfte Tabellenzeilen. Wenn von der primären Zeile für eine Nachschlage- oder eine zugehörige Zeilenspalte eine Änderung vorgenommen wird und eine zugehörige Zeile anschließend dieselbe Spalte aktualisiert, wird der zugehörige Zeilenwert beibehalten. Im Allgemeinen sollten ein Nachschlagespaltenwert und sein Äquivalent in Entity.RelatedEntities für dieselbe Beziehung nicht gleichzeitig verwendet werden.
var account = new Entity("account");
account.Id = retrievedAccount.Id;
//Define relationships
var primaryContactRelationship = new Relationship("account_primary_contact");
var AccountTasksRelationship = new Relationship("Account_Tasks");
//Update the account name
account["name"] = "New Account name";
//Update the email address for the primary contact of the account
var contact = new Entity("contact");
contact.Id = retrievedAccount.RelatedEntities[primaryContactRelationship]
.Entities.FirstOrDefault().Id;
contact["emailaddress1"] = "someone_a@example.com";
List<Entity> primaryContacts = new List<Entity>();
primaryContacts.Add(contact);
account.RelatedEntities.Add(primaryContactRelationship, new EntityCollection(primaryContacts));
// Find related Tasks that need to be updated
List<Entity> tasksToUpdate = retrievedAccount
.RelatedEntities[AccountTasksRelationship].Entities
.Where(t => t["subject"].Equals("Example Task")).ToList();
// A list to put the updated tasks
List<Entity> updatedTasks = new List<Entity>();
//Fill the list of updated tasks based on the tasks that need to but updated
tasksToUpdate.ForEach(t => {
var updatedTask = new Entity("task");
updatedTask.Id = t.Id;
updatedTask["subject"] = "Updated Subject";
updatedTasks.Add(updatedTask);
});
//Set the updated tasks to the collection
account.RelatedEntities.Add(AccountTasksRelationship, new EntityCollection(updatedTasks));
//Update the account and related contact and tasks
svc.Update(account);
Nach doppelten Datensätzen suchen
Beim Aktualisieren einer Tabellenzeile können Sie die Werte ändern, sodass die Zeile ein Duplikat einer anderen Zeile darstellt. Weitere Informationen: Erkennen von doppelten Daten mit dem SDK für .NET
Aktualisierung mit Alternativschlüsseln
Wenn für eine Tabelle ein Alternativschlüssel definiert ist, können Sie diesen anstelle des Primärschlüssels verwenden, um eine Zeile zu aktualisieren. Sie können die früh gebundene Klasse nicht verwendet, um den Alternativschlüssel anzugeben. Sie müssen den Konstruktor Entity(String, KeyAttributeCollection) verwenden, um den Alternativschlüssel anzugeben.
Bei Nutzung von Typen mit früher Bindung können Sie Entity mittels der Entity.ToEntity<T>-Methode in eine führ gebundene Klasse konvertieren.
Das folgende Beispiel zeigt, wie ein Account
mit einem Alternativschlüssel aktualisiert wird, der für die Spalte accountnumber
(Attribut) definiert ist.
Wichtig
Für die meisten Tabellen für Geschäftsdaten sind keine alternativen Schlüssel definiert. Diese Methode kann nur verwendet werden, wenn die Umgebung so konfiguriert ist, dass ein Alternativschlüssel für eine Tabelle definiert wird.
var accountNumberKey = new KeyAttributeCollection();
accountNumberKey.Add(new KeyValuePair<string, object>("accountnumber", "123456"));
Account exampleAccount = new Entity("account", accountNumberKey).ToEntity<Account>();
exampleAccount.Name = "New Account Name";
svc.Update(exampleAccount);
Weitere Informationen:
- Arbeiten mit Alternativschlüsseln
- Verwenden Sie einen Alternativschlüssel, um auf einen Datensatz zu verweisen
Aktualisieren und Löschen von Datensätzen in elastischen Tabellen
Wenn Sie Daten aus elastischen Tabellen, die in Partitionen gespeichert sind, aktualisieren oder löschen, geben Sie beim Zugriff auf diese Daten unbedingt den Partitionsschlüssel an. Weitere Informationen: Partitioning und horizontale Skalierung
Verwendung von Upsert
In der Regel müssen Sie in den Datenenintegrationsszenarien Daten in den Dataverse aus anderen Quellen erstellen oder aktualisieren. Dataverse hat ggf. bereits Datensätze mit dem gleichen eindeutigen Bezeichner, die möglicherweise ein Alternativschlüssel sind. Wenn eine Tabellenzeile vorhanden ist, möchten Sie sie aktualisieren. Sollte er nicht vorhanden sein, erstellen Sie ihn, damit die Daten, die hinzugefügt werden, mit den Quelldaten synchronisiert werden. Dieses Szenario ist erforderlich, wenn Sie upsert verwenden möchten.
Das folgende Beispiel nutzt ein UpsertRequest zweimal. Bei der erstmaligen Erstellung der Kontozeile und bei ihrer zweiten Aktualisierung, weil sie über einen Wert accountnumber
verfügt und ein Alternativschlüssel vorhanden ist, der diese Spalte (Attribut) verwendet.
Bei beiden Aufrufen gibt die UpsertResponse.RecordCreated-Eigenschaft an, ob durch den Vorgang eine Zeile erstellt wurde oder nicht.
// This environment has an alternate key set for the accountnumber attribute.
//Instantiate account entity with accountnumber value
var account = new Entity("account", "accountnumber", "0003");
account["name"] = "New Account";
//Use Upsert the first time
UpsertRequest request1 = new UpsertRequest() {
Target = account
};
//The new entity is created
var response1 = (UpsertResponse)svc.Execute(request1);
Console.WriteLine("Record Created: {0}",response1.RecordCreated); //true
//Update the name of the existing account entity
account["name"] = "Updated Account";
//Use Upsert for the second time
UpsertRequest request2 = new UpsertRequest()
{
Target = account
};
//The existing entity is updated.
var response2 = (UpsertResponse)svc.Execute(request2);
Console.WriteLine("Record Created: {0}", response2.RecordCreated); //false
Weitere Informationen: Einen Datensatz mit Upsert einfügen oder aktualisieren
Delete
Die Iorganization.Service.Delete-Methode benötigt lediglich den logischen Namen der Tabelle und den eindeutigen Bezeichner. Unabhängig davon, ob Sie eine spät gebundene Enitätsklasse oder eine früh gebundene Entitätsklasse verwenden, können Sie die folgenden Syntax für einen Löschvorgang verwenden, indem Sie die Eigenschafteb Entity.LogicalName zbd Entity.ID übergeben.
svc.Delete(retrievedEntity.LogicalName, retrievedEntity.Id);
Alternativ können Sie auch dynamische Werte verwenden:
svc.Delete("account", new Guid("e5fa5509-2582-e811-a95e-000d3af40ae7"));
Wichtig
Löschvorgänge können kaskadierende Vorgänge initiieren, die untergeordnete Zeilen löschen können, um die Datenintegrität abhängig von der für Beziehungen in der Umgebung definierten Logik beizubehalten. Weitere Informationen: Tabellenbeziehungs-Verhalten
Die DeleteRequest-Klasse nutzen
Sie können die DeleteRequest-Klasse anstelle der IOrganizationService.Delete-Methode verwenden. Sie ist jedoch nur erforderlich, wenn Sie ein optimistisches Parallelitätsverhalten definieren möchten.
var retrievedEntity = new Entity("account")
{
Id = new Guid("c81ffd82-cd82-e811-a95c-000d3af49bf8"),
RowVersion = "986335"
};
var request = new DeleteRequest()
{
Target = retrievedEntity.ToEntityReference(),
ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches
};
svc.Execute(request);
Verhalten der optimistischen Parallelität
Sie können das Verhalten der optimistischen Parallelität für den Vorgang angeben, indem Sie die ConcurrencyBehavior
-Eigenschaft der UpdateRequest- oder DeleteRequest-Klassen festlegen.
Die Logik zum Aktualisieren oder Löschen der Zeile kann auf veralteten Daten basieren. Wenn die aktuellen Daten sich unterscheiden, da sie geändert wurden, seit sie abgerufen wurden, enthält die optimistische Parallelität eine Möglichkeit, ein Update oder einen Löschvorgang abzubrechen, sodass möglicherweise die Anfrage wiederholt werden kann, um die aktuellen Daten zu nutzen.
Um festzustellen, ob die Zeile geändert wurde, müssen Sie nicht alle Werte vergleichen. Sie können die Eigenschaft RowVersion verwenden, um zu sehen, ob sich an der Zeile etwas geändert hat.
Das folgende Beispiel wird nur erfolgreich ausgeführt, wenn:
- Die
RowVersion
der Zeile in der Datenbank ist gleich986323
. - Die Kontotabelle für die optimistische Parallelität aktiviert ist (EntityMetadata.IsOptimisticConcurrencyEnabled-Eigenschaft ist
true
) - Die Eigenschaft
RowVersion
wird für die mit der Anforderung übergebene Zeile festgelegt.
Wenn RowVersion
nicht übereinstimmt, tritt ein Fehler mit der The version of the existing record doesn't match the RowVersion property provided.
Meldung auf.
var retrievedAccount = new Account()
{
Id = new Guid("a976763a-ba1c-e811-a954-000d3af451d6"),
RowVersion = "986323"
};
var account = new Account();
account.Id = retrievedAccount.Id;
account.RowVersion = retrievedAccount.RowVersion;
// set attribute values
account.CreditOnHold = true;
//Update the account
var request = new UpdateRequest()
{
Target = account,
ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches
};
try
{
svc.Execute(request);
}
catch (FaultException<OrganizationServiceFault> ex)
{
switch (ex.Detail.ErrorCode)
{
case -2147088254: // ConcurrencyVersionMismatch
case -2147088253: // OptimisticConcurrencyNotEnabled
throw new InvalidOperationException(ex.Detail.Message);
case -2147088243: // ConcurrencyVersionNotProvided
throw new ArgumentNullException(ex.Detail.Message);
default:
throw ex;
}
}
Weitere Informationen:
Vorgängerupdatenachrichten
Es gibt mehrere veraltete spezialisierte Nachrichten, die Aktualisierungsvorgänge ausführen. In früheren Versionen war es erforderlich, diese Nachrichten zu verwenden. Jetzt sollten die selben Vorgänge mithilfe von IOrganizationService.Update oder UpdateRequest-Klasse mit der IOrganizationService.Execute-Methode ausgeführt werden.
Veraltete Nachrichtenanforderung | Zu aktualisierende(s) Attribut(e) |
---|---|
AssignRequest | <Entität>.OwnerId |
SetStateRequest | <Entität>.StateCode <Entität>. StatusCode |
SetParentSystemUserRequest | SystemUser.ParentSystemUserId |
SetParentTeamRequest | Team.BusinessUnitId |
SetParentBusinessUnitRequest | BusinessUnit.ParentBusinessUnitId |
SetBusinessEquipmentRequest | Arbeitsgerät.BusinessUnitId |
SetBusinessSystemUserRequest | SystemUser.BusinessUnitId |
<Entität> verweist auf eine beliebige Entität, die dieses Attribut bereitstellt.
Wichtig
Wenn Sie die Spalte StateCode
aktualisieren, ist es wichtig, dass Sie immer den gewünschten StatusCode
festlegen.
StateCode
und StatusCode
haben abhängige Werte. Es kann mehrere gültige StatusCode
-Werte für einen bestimmten StateCode
-Wert geben, aber für jede StateCode
-Spalte ist ein einziger DefaultStatus-Wert konfiguriert. Wenn Sie StateCode
aktualisieren, ohne einen StatusCode
anzugeben, wird der Standardstatuswert vom System festgelegt.
Wenn die Überwachung für die Tabelle und die StatusCode
-Spalte aktiviert ist, wird der geänderte Wert für die StatusCode
-Spalte nicht in den Überwachungsdaten erfasst, es sei denn, er wird im Aktualisierungsvorgang angegeben.
Weitere Informationen: Verhalten spezieller Vorgänge mithilfe Update
Siehe auch
Tabellenzeilen mit dem SDK für .NET erstellen
Abrufen einer Tabellenzeile über die SDK für .NET
Zuordnen und Aufheben der Zuordnung von Tabellenzeilen über das SDK für .NET