Mettre à jour et supprimer des lignes de table à l’aide du SDK pour .NET
Cet article comprend des exemples utilisant à la fois des styles de programmation à liaison anticipée et à liaison tardive. Pour plus d’informations, voir : Programmation avec liaison tardive et anticipée à l’aide du SDK pour .NET
Chacun des exemples utilise une variable svc
qui représente une instance d’une classe qui met en place les méthodes dans l’interface IOrganizationService. Pour plus d’informations sur les classes qui prennent en charge cette interface, consultez l’interface IOrganizationService.
Important
Lors de la mise à jour d’une ligne de tableau, n’incluez que les colonnes que vous modifiez. La simple mise à jour des colonnes d’une ligne de tableau que vous avez précédemment récupérée mettra à jour chaque colonne même si la valeur est inchangée. Cela peut entraîner des événements système qui peuvent déclencher une logique métier qui prévoit que les valeurs aient réellement changé. Cela peut également donner l’impression que les colonnes ont été mises à jour dans les données d’audit alors qu’elles n’ont en fait pas changé.
Vous devez créer une instance Entity
, définissez l’attribut ID et toutes les valeurs d’attribut que vous modifiez, et utilisez cette instance d’entité pour mettre à jour la ligne de la table.
Note
La définition de colonne comprend une propriété RequiredLevel
. Lorsque celui-ci est défini sur SystemRequired
, vous ne pouvez pas définir ces colonnes sur une valeur nulle. Si vous tentez de le faire, vous obtiendrez le code d’erreur -2147220989
avec le message Attribute: <attribute name> cannot be set to NULL
.
Plus d’information : Niveau d’exigence de la colonne (attribut)
Mise à jour de base
Les deux exemples ci-dessous utilisent la méthode IOrganizationService.Update pour définir les valeurs de colonne d’une ligne de table précédemment extraite.
Utilisez la propriété Entity.Id pour transférer la valeur de l’identificateur unique de la ligne extraite vers l’instance d’entité utilisée pour exécuter l’opération de mise à jour.
Note
Si vous essayez de mettre à jour une ligne sans valeur de clé primaire, vous obtiendrez l’erreur : Entity Id must be specified for Update
.
Si vous n’avez pas de valeur de clé primaire, vous pouvez également mettre à jour les lignes à l’aide de clés secondaires. Informations complémentaires : Mettre à jour avec une clé secondaire
L’exemple suivant montre comment utiliser la classe Entity pour créer un compte à l’aide de la méthode IOrganizationService.Update.
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);
Utiliser la classe UpdateRequest
Au lieu d’utiliser la méthode IOrganizationService.Update, vous pouvez utiliser la classe Entity à liaison tardive ou les classes d’entité à liaison anticipée générées avec la classe UpdateRequest en définissant l’instance d’entité sur la propriété UpdateRequest.Target, puis en utilisant la méthode IOrganizationService.Execute.
Note
La classe UpdateResponse n’a aucune propriété. Lorsqu’elle est renvoyée par la méthode IOrganizationService.Execute, il n’est pas nécesssaire d’y faire référence.
var request = new UpdateRequest()
{ Target = account };
svc.Execute(request);
Quand utiliser la classe UpdateRequest
Vous devez utiliser la classe UpdateRequest si vous souhaitez transmettre des paramètres facultatifs. Il existe deux cas où vous pourriez avoir besoin de paramètres spéciaux.
- Quand vous souhaitez que les règles de détection de doublons soient appliquées. Pour plus d’informations : Détecter les données dupliquées avec le SDK pour .NET
- Lorsque vous créez une ligne de table qui représente un composant de solution, tel que WebResource et souhaitez l’associer à une solution spécifique. Dans ce cas, vous incluriez la valeur Solution.UniqueName à l’aide du paramètre
SolutionUniqueName
. Pour plus d’informations : Utiliser des messages avec le SDK pour .NET
Vous devez également utiliser la classe UpdateRequest si vous souhaitez préciser un comportement d’accès concurrentiel optimiste. Pour plus d’informations : Comportement de l’accès concurrentiel optimiste
Utilise la classe UpdateMultipleRequest
La classe UpdateMultipleRequest est le moyen le plus performant de mettre à jour plusieurs enregistrements dans une seule demande. Pour plus d’informations : Messages d’opération en bloc
Mettre à jour les entités associées en une opération
De la même manière que vous pouvez Créer des lignes de table associées en une seule opération, vous pouvez également mettre à jour les lignes de tableau associées.
Pour mettre à jour les lignes de table associées, vous devez récupérer une ligne avec les lignes associées afin de pouvoir accéder aux valeurs d’ID. Pour plus d’informations : Extraire avec des lignes associées.
Important
Les mises à jour des lignes sont effectuées dans un ordre spécifique. Tout d’abord, les lignes du tableau principal sont traitées, puis les lignes du tableau associées sont traitées. Si une modification est apportée par la ligne principale pour une recherche ou une colonne de ligne associée, puis qu’une ligne associée met à jour la même colonne, la valeur de la ligne associée est conservée. En général, une valeur de colonne de recherche et son équivalent dans Entity.RelatedEntities pour la même relation ne doivent pas être utilisés en même temps.
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);
Rechercher des enregistrements dupliqués
Lors de la mise à jour d’une ligne de table, vous pouvez modifier les valeurs afin que la ligne représente un doublon d’une autre ligne. Pour plus d’informations : Détecter les données dupliquées avec le SDK pour .NET
Mettre à jour avec une clé secondaire
Si vous avez défini une clé secondaire pour une table, vous pouvez l’utiliser à la place de la clé primaire pour mettre à jour une ligne. Vous ne pouvez pas utiliser la classe à liaison anticipée pour spécifier la clé secondaire. Vous devez utiliser le constructeur Entity(String, KeyAttributeCollection) pour spécifier la clé secondaire.
Si vous souhaitez utiliser des types à liaison anticipée, vous pouvez convertir Entity en une classe à liaison anticipée à l’aide de la méthode Entity.ToEntity<T>.
L’exemple suivant montre comment mettre à jour un Account
en utilisant un clé secondaire défini pour la colonne accountnumber
(attribut).
Important
La plupart des tables de données d’entreprise n’ont pas de clés secondaires définies. Cette méthode ne peut être utilisée que lorsque l’environnement est configuré pour définir un clé secondaire pour une table.
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);
Pour plus d′informations :
Mettre à jour et supprimer des enregistrements dans des tables élastiques
Si vous mettez à jour ou supprimez des données de table élastique stockées dans des partitions, assurez-vous de spécifier la clé de partition lors de l’accès à ces données. En savoir plus : Partitionnement et mise à l’échelle horizontale
Utiliser Upsert
Généralement dans les scénarios d’intégration des données, vous devez créer ou mettre à jour les données dans Dataverse depuis d’autres sources. Dataverse peut avoir déjà des enregistrements avec le même identifiant unique, qui peut être une clé secondaire. S’il existe une ligne de tableau, vous souhaitez la mettre à jour. S’il n’existe pas, vous souhaitez le créer de telle sorte que les données ajoutées sont synchronisées avec les données sources. Il s’agit du scénario lorsque vous souhaitez utiliser Upsert.
L’exemple suivant utilise deux fois UpsertRequest. La première fois que la ligne de compte est créée et la deuxième fois qu’elle est mise à jour car elle a une valeur accountnumber
et une clé secondaire utilise cette colonne (attribut).
Pour les deux appels, la propriété UpsertResponse.RecordCreated indique si l’opération a créé une ligne ou non.
// 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
Pour plus d’informations : Utilisation de Upsert pour insérer ou mettre à jour un enregistrement
Delete
La méthode IOrganizationService.Delete requiert simplement le nom logique de la table et l’identificateur unique. Peu importe si vous utilisez une classe Entity à liaison tardive ou une classe à liaison anticipée générée, vous pouvez utiliser la syntaxe suivante pour une opération de suppression en transmettant les propriétés Entity.LogicalName et Entity.Id.
svc.Delete(retrievedEntity.LogicalName, retrievedEntity.Id);
Ou vous pouvez utiliser les valeurs :
svc.Delete("account", new Guid("e5fa5509-2582-e811-a95e-000d3af40ae7"));
Important
Les opérations de suppression peuvent lancer des opérations en cascade qui peuvent supprimer des lignes enfants pour maintenir l’intégrité des données en fonction de la logique définie pour le Relations dans l’environnement. Pour plus d’informations : Comportement des relations de table
Utiliser la classe DeleteRequest
Vous pouvez utiliser la classe DeleteRequest au lieu de la méthode IOrganizationService.Delete, mais elle n’est requise que lorsque vous souhaitez spécifier un comportement d’accès concurrentiel optimiste.
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);
Comportement d’accès concurrentiel optimiste
Vous pouvez préciser le comportement d’accès concurrentiel optimiste pour l’opération en définissant la propriété ConcurrencyBehavior
des classes UpdateRequest ou DeleteRequest.
La logique de mise à jour ou de suppression de la ligne peut être basée sur des données obsolètes. Si les données actuelles diffèrent, car elles ont changé depuis leur extraction, l’accès concurrentiel optimiste permet d’annuler une mise à jour ou de supprimer une opération de telle sorte que vous pouvez la récupérer et utiliser les données actuelles afin de déterminer s’il convient de poursuivre ou non.
Pour déterminer si la ligne a été modifiée, vous n’avez pas besoin de comparer toutes les valeurs, vous pouvez utiliser la propriété RowVersion pour voir si elle a changé.
L’exemple suivant se produit uniquement quand :
- La
RowVersion
de la ligne dans la base de données est égale à986323
- La table de compte est activée pour l’accès concurrentiel optimiste (la propriété EntityMetadata.IsOptimisticConcurrencyEnabled est
true
) - La propriété
RowVersion
est définie sur la ligne transmise avec la requête.
Si RowVersion
ne correspond pas, une erreur survient avec le message The version of the existing record doesn't match the RowVersion property provided.
.
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;
}
}
Pour plus d’informations :
Anciens messages de mise à jour
Il existe plusieurs messages spécialisés déconseillés qui exécutent des opérations de mise à jour. Dans les versions antérieures, il était nécessaire d’utiliser ces messages, mais maintenant les mêmes opérations doivent être exécutées en utilisant IOrganizationService.Update ou la classe UpdateRequest avec la méthode IOrganizationService.Execute.
Demande de message déconseillé | Attribut(s) à mettre à jour |
---|---|
AssignRequest | <entity>.OwnerId |
SetStateRequest | <entity>.StateCode <entity>. StatusCode |
SetParentSystemUserRequest | SystemUser.ParentSystemUserId |
SetParentTeamRequest | Team.BusinessUnitId |
SetParentBusinessUnitRequest | BusinessUnit.ParentBusinessUnitId |
SetBusinessEquipmentRequest | Equipment.BusinessUnitId |
SetBusinessSystemUserRequest | SystemUser.BusinessUnitId |
<entity> fait référence à toute entité qui fournit cet attribut.
Important
Lorsque vous mettez à jour la colonne StateCode
, il est important de toujours définir le StatusCode
souhaité.
StateCode
et StatusCode
ont des valeurs dépendantes. Il peut y avoir plusieurs valeurs StatusCode
valides pour une valeur StateCode
donnée, mais chaque colonne StateCode
a une seule valeur de DefaultStatus configurée. Lorsque vous mettez à jour StateCode
sans spécifier de StatusCode
, la valeur d’état par défaut est définie par le système.
De plus, lorsque l’audit est activé sur la table et la colonne StatusCode
, la valeur modifiée de la colonne StatusCode
ne sera pas capturée dans les données d’audit, sauf si elle est spécifiée dans l’opération de mise à jour.
Pour plus d’informations : Comportement des opérations de mise à jour spécifiques
Voir aussi
Créer des lignes de table à l’aide du SDK pour .NET
Récupérer une ligne de table à l’aide du SDK pour .NET
Associer et dissocier des lignes de tables à l’aide du SDK pour .NET