Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Pour obtenir les meilleures performances lors de l’exécution d’opérations sur plusieurs lignes d’une table Microsoft Dataverse, utilisez l’un des messages d’opération en bloc suivants :
-
CreateMultiple: crée plusieurs enregistrements du même type dans une seule demande. -
UpdateMultiple: met à jour plusieurs enregistrements du même type dans une seule demande. -
UpsertMultiple: crée ou met à jour plusieurs enregistrements du même type dans une seule demande. -
DeleteMultiple: pour les tables élastiques uniquement. Supprime plusieurs enregistrements du même type dans une seule demande.
Note
Pour obtenir des conseils sur les options lors de l’exécution d’opérations en bloc, telles que le moment d’utiliser ces API par rapport aux API de traitement par lots, ExecuteMultipleconsultez Optimiser les performances pour les opérations en bloc.
Exemples
Les exemples de code suivants montrent comment utiliser les messages d’opération en bloc. Vous pouvez télécharger des exemples depuis github.com/microsoft/PowerApps-Samples :
- Exemple : SDK pour .NET - Utiliser des opérations en bloc
- Exemple : Utilisation d'opérations en bloc d'API Web
- Exemple de code de table élastique
CreateMultiple
Crée plusieurs enregistrements du même type dans une seule demande.
Utilise la classe CreateMultipleRequest.
/// <summary>
/// Demonstrates the use of the CreateMultiple Message
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToCreate">A list of records of the same table to create.</param>
/// <returns>The Guid values of the records created.</returns>
static Guid[] CreateMultipleExample(IOrganizationService service,
List<Entity> recordsToCreate)
{
// Create an EntityCollection populated with the list of entities.
EntityCollection entities = new(recordsToCreate)
{
// All the records must be for the same table.
EntityName = recordsToCreate[0].LogicalName
};
// Instantiate CreateMultipleRequest
CreateMultipleRequest createMultipleRequest = new()
{
Targets = entities,
};
// Send the request
CreateMultipleResponse createMultipleResponse =
(CreateMultipleResponse)service.Execute(createMultipleRequest);
// Return the Ids of the records created.
return createMultipleResponse.Ids;
}
Mettre à jour plusieurs
Met à jour plusieurs enregistrements du même type dans une seule demande.
Tout comme lorsque vous mettez à jour des enregistrements individuels, les données que vous envoyez à l’aide UpdateMultiple doivent contenir uniquement les valeurs que vous modifiez. Pour plus d’informations, consultez les enregistrements de mise à jour avec le Kit de développement logiciel (SDK) pour .NET et les enregistrements de mise à jour avec l’API web.
Utilise la classe UpdateMultipleRequest.
/// <summary>
/// Demonstrates the use of the UpdateMultiple message.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToUpdate">A list of records to create.</param>
static void UpdateMultipleExample(IOrganizationService service, List<Entity> recordsToUpdate) {
// Create an EntityCollection populated with the list of entities.
EntityCollection entities = new(recordsToUpdate)
{
// All the records must be for the same table.
EntityName = recordsToUpdate[0].LogicalName
};
// Use UpdateMultipleRequest
UpdateMultipleRequest updateMultipleRequest = new()
{
Targets = entities,
};
service.Execute(updateMultipleRequest);
}
Enregistrements en double dans le paramètre « UpdateMultiple Targets »
UpdateMultiple ne prend pas en charge plusieurs enregistrements avec la même clé primaire ou d’autres valeurs de clé dans la charge utile. Lorsque plusieurs enregistrements dans le Targets paramètre sont identifiés de manière unique par une clé primaire ou une clé alternative, l’opération est effectuée sur le premier enregistrement uniquement. L’opération ignore les enregistrements suivants avec les mêmes valeurs de clé dans la charge utile.
Ce comportement est différent de UpsertMultiple.
UpsertMultiple
Permet Upsert d’intégrer des données à des sources externes lorsque vous ne savez pas si la table existe dans Dataverse. Les opérations Upsert dépendent fréquemment de clés alternatives pour identifier les enregistrements. Utilisez UpsertMultiple pour exécuter des opérations Upsert en bloc.
Utilise la classe UpsertMultipleRequest.
Cette méthode statique UpsertMultipleExample dépend d’une table samples_bankaccount qui a une colonne de chaîne nommée samples_accountname configurée comme clé secondaire. Il comporte également une colonne de chaîne nommée samples_description. Ce code utilise le constructeur Entité qui définit keyName et keyValue pour spécifier la valeur clé secondaire.
/// <summary>
/// Demonstrates using UpsertMultiple with alternate key values
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
static void UpsertMultipleExample(IOrganizationService service)
{
var tableLogicalName = "samples_bankaccount";
// samples_accountname string column is configued as an alternate key
// for the samples_bankaccount table
var altKeyColumnLogicalName = "samples_accountname";
// Create one record to update with upsert
service.Create(new Entity(tableLogicalName)
{
Attributes =
{
{altKeyColumnLogicalName, "Record For Update"},
{"samples_description","A record to update using Upsert" }
}
});
// Using the Entity constructor to specify alternate key
Entity toUpdate = new(
entityName: tableLogicalName,
keyName: altKeyColumnLogicalName,
// Same alternate key value as created record.
keyValue: "Record For Update");
toUpdate["samples_description"] = "Updated using Upsert";
Entity toCreate = new(
entityName: tableLogicalName,
keyName: altKeyColumnLogicalName,
keyValue: "Record For Create");
toCreate["samples_description"] = "A record to create using Upsert";
// Add the records to a collection
EntityCollection records = new()
{
EntityName = tableLogicalName,
Entities = { toUpdate, toCreate }
};
// Send the request
UpsertMultipleRequest request = new()
{
Targets = records
};
var response = (UpsertMultipleResponse)service.Execute(request);
// Process the responses:
foreach (UpsertResponse item in response.Results)
{
Console.WriteLine($"Record {(item.RecordCreated ? "Created" : "Updated")}");
}
}
Sortie :
Record Updated
Record Created
La création ou la mise à jour d’un enregistrement dans cet exemple dépend de l’existence ou non d’enregistrements avec la valeur sample_keyattribute correspondante. Aucune donnée n’est renvoyée pour indiquer si un enregistrement a été créé ou mis à jour.
Exemples SDK
Dans l’exemple : Kit de développement logiciel (SDK) pour .NET Utiliser des opérations en bloc, recherchez le projet UpsertMultiple.
Disponibilité
UpsertMultiple est disponible pour les tables prenant en charge CreateMultiple et UpdateMultiple. Cette prise en charge inclut toutes les tables élastiques. Les requêtes trouvées dans La disponibilité avec des tables standard ne retournent pas de résultats, UpsertMultiplemais vous pouvez les utiliser pour détecter si une table prend en charge les deux CreateMultiple et UpdateMultiple.
Ces requêtes ne retournent pas les résultats du UpsertMultiple message. Une table qui prend en charge à la fois CreateMultiple et UpdateMultiple peut également prendre en charge UpsertMultiple.
Enregistrements dupliqués dans le paramètre "UpsertMultiple Targets"
UpsertMultiple ne prend pas en charge plusieurs enregistrements avec la même clé primaire ou d’autres valeurs de clé dans la charge utile. Lorsque plusieurs enregistrements du Targets paramètre sont identifiés de manière unique par une clé primaire ou alternative, UpsertMultiple retourne une erreur.
Ce comportement est différent de UpdateMultiple.
SupprimerPlusieurs
Supprimez plusieurs lignes de données dans des tables élastiques avec une seule requête.
Utilisez la classe OrganizationRequest , car le Kit de développement logiciel (SDK) pour .NET n’a pas de DeleteMultipleRequest classe. Pour plus d’informations, consultez utiliser des messages avec le Kit de développement logiciel (SDK) pour .NET.
La méthode statique suivante DeleteMultipleExample utilise le DeleteMultiple message avec la classe OrganizationRequest pour supprimer plusieurs lignes de la contoso_SensorData table élastique en utilisant la clé alternative partitionid pour identifier de manière unique les lignes.
public static void DeleteMultipleExample(IOrganizationService service)
{
string tableLogicalName = "contoso_sensordata";
List<EntityReference> entityReferences = new() {
{
new EntityReference(logicalName: tableLogicalName,
keyAttributeCollection: new KeyAttributeCollection
{
{ "contoso_sensordataid", "3f56361a-b210-4a74-8708-3c664038fa41" },
{ "partitionid", "deviceid-001" }
})
},
{ new EntityReference(logicalName: tableLogicalName,
keyAttributeCollection: new KeyAttributeCollection
{
{ "contoso_sensordataid", "e682715b-1bba-415e-b2bc-de9327308423" },
{ "partitionid", "deviceid-002" }
})
}
};
OrganizationRequest request = new(requestName:"DeleteMultiple")
{
Parameters = {
{"Targets", new EntityReferenceCollection(entityReferences)}
}
};
service.Execute(request);
}
Suppression multiple de la disponibilité
DeleteMultiple n’est pris en charge que pour les tables élastiques. Les tables élastiques ne prennent pas en charge le comportement en cascade des relations de table, ce qui entraîne des délais d’exécution imprévisibles pour les opérations de suppression. Si vous utilisez DeleteMultiple sur une table standard, vous obtenez l’erreur : DeleteMultiple has not yet been implemented.
Exemples de DeleteMultiple
Vous pouvez trouver un exemple de code sur GitHub dans github.com/microsoft/PowerApps-Samples :
- Exemple de code de table élastique
- Dans Exemple : SDK pour .NET Utiliser des opérations groupées ou Exemple : API Web Utiliser des opérations groupées, modifiez le
Settings.csfichier de configuration et choisissez l’optionUseElastic.
Utilisation des tables standard et élastiques
Les tables standard et élastiques bénéficient d’une amélioration significative des performances lorsque vous utilisez des messages d’opération en bloc, mais vous devez les utiliser différemment. Le tableau suivant résume les différences.
| Différence | Standard | Élastique |
|---|---|---|
| Nombre d’enregistrements | Les opérations sont plus efficaces avec un plus grand nombre d’enregistrements. Il n’y a pas de limite définie sur le nombre d’enregistrements, mais il existe des limites de taille des messages et de temps. Envoyez 100 à 1 000 enregistrements à la fois. | Envoyez 100 enregistrements à la fois. |
| Comportement en cas d’erreur | Toutes les opérations sont annulées en cas d’erreur. | Un succès partiel est possible. |
| Disponibilité | Toutes les tables standard ne prennent pas en charge ces messages. | Les messages sont disponibles pour toutes les tables élastiques. |
| SupprimerPlusieurs | Non disponible. Utilisez la classe BulkDeleteRequest du SDK ou l’action BulkDelete de l’API Web à la place. Découvrez comment supprimer des données en bloc. | Utiliser la classe DeleteMultipleRequest du kit de développement logiciel (SDK) ou l’action DeleteMultiple de l’API web |
L’utilisation de tables standard et élastiques est différente car les tables standard utilisent Azure SQL et prennent en charge les transactions. Les tables élastiques utilisent Azure Cosmos DB, qui ne prend pas en charge les transactions, mais gère de grandes quantités de données à des niveaux élevés de débit avec une faible latence. Les sections suivantes fournissent plus de détails. En savoir plus sur les opérations en bloc sur les tables élastiques.
Nombre d’enregistrements
Le nombre d’enregistrements à joindre à chaque demande dépend de l’utilisation de tables standards ou élastiques.
Astuce
Les tables standard et élastiques ont un meilleur débit lorsque vous envoyez des messages d’opération en bloc en parallèle.
Nombre d’enregistrements avec des tables standard
Les opérations en bloc avec des tables standard sont optimisées pour exécuter des opérations sur plusieurs lignes au sein d’une même transaction. Les opérations deviennent plus efficaces, et donc plus performantes en général, à mesure que le nombre d’opérations par demande augmente. Cette optimisation rend également les étapes de plugin enregistrées pour l’opération en bloc plus efficaces. Chaque fois qu’un plug-in est appelé pour une seule opération, le processus nécessite quelques millisecondes pour appeler la classe plug-in contenant la logique. Lorsque vous inscrivez un plug-in pour un message d’opération en bloc, la classe est appelée une seule fois et peut traiter toutes les opérations plus efficacement. Découvrez comment écrire des plug-ins pour CreateMultiple et UpdateMultiple.
Cet avantage en matière de performance vous encourage à envoyer le plus grand nombre d’enregistrements que possible dans chaque requête. Cependant, à mesure que le nombre d’enregistrements augmente, la taille de la demande devient plus grande et nécessite un temps de traitement plus long. Finalement, vous rencontrez des limites de durée et de taille de message. Si vous atteignez ces limites, toute l’opération échoue. Il n’y a pas de limite définie pour le nombre d’enregistrements à envoyer. Vous devrez peut-être expérimenter pour trouver le meilleur nombre. En règle générale, 100 à 1 000 enregistrements par demande sont un endroit raisonnable pour commencer si la taille des données d’enregistrement est petite et qu’il n’y a pas de plug-ins. Les types d’erreurs que vous pouvez rencontrer peuvent généralement être résolus en envoyant moins d’enregistrements avec chaque requête. Incluez la possibilité de configurer le nombre d’entités envoyées afin que vous puissiez vous adapter envoyant moins.
Nombre de dossiers utilisant des tables élastiques
Comme il n’y a pas de transaction avec les tables élastiques, il n’y a aucun avantage en termes de performances à essayer d’envoyer le plus grand nombre d’enregistrements par demande. Envoyez 100 opérations par requête et envoyez des demandes en parallèle pour atteindre le débit maximal.
Sur le comportement des erreurs
Le comportement en cas d’erreur dépend de l’utilisation de tables standard ou de tables élastiques.
En cas de comportement d’erreur avec des tables standard
Toute erreur qui se produit dans une opération en bloc avec une table standard entraîne l’annulation de toute l’opération. Utilisez uniquement des opérations en bloc sur des tables standard lorsque vous avez un degré élevé de confiance que toutes les opérations réussissent. Pour autoriser la restauration de l’ensemble d’opérations en cas d’échec de l’opération en bloc, envisagez d’utiliser la classe ExecuteMultipleRequest du SDK ou l’API $batchWeb. Si le taux de réussite de votre tentative initiale est faible, cette stratégie se traduit par de moins bonnes performances. N’utilisez cette stratégie de retour que lorsque vous vous attendez à ce que la plupart des opérations réussissent.
Gestion des erreurs avec les tables élastiques
Avec des tables élastiques, une opération en bloc peut réussir partiellement. Vous pouvez utiliser les détails de l’erreur pour identifier les enregistrements qui ont échoué.
Lorsque vous utilisez le SDK pour exécuter une opération en bloc avec une table élastique, une exception FaultException de type OrganizationServiceFault est déclenchée en cas d’échec. Utilisez le code suivant pour obtenir le statut de chaque enregistrement.
if (ex.Detail.ErrorDetails.TryGetValue("Plugin.BulkApiErrorDetails", out object errorDetails))
{
List<BulkApiErrorDetail> bulkApiErrorDetails = JsonConvert.DeserializeObject<List<BulkApiErrorDetail>>(errorDetails.ToString());
}
public class BulkApiErrorDetail
{
public int RequestIndex { get; set; }
public string Id { get; set; }
public int StatusCode { get; set; }
}
Disponibilité
La disponibilité des messages d’opération en bloc dépend de l’utilisation de tables standard ou de tables élastiques. Toutes les tables élastiques prennent en charge les messages CreateMultiple, UpdateMultiple, UpsertMultiple et DeleteMultiple.
Disponibilité avec des tables standard
Vous pouvez utiliser les messages d’opération en bloc CreateMultiple et UpdateMultiple pour les tables standard personnalisées et de nombreuses tables standard courantes, mais pas toutes. Testez si les tables standard individuelles prennent en charge ces messages. Les exemples suivants vous montrent comment y parvenir.
Utilisez cette méthode statique pour détecter si une table donnée prend en charge CreateMultiple ou UpdateMultiple.
/// <summary>
/// Detect whether a specified message is supported for the specified table.
/// </summary>
/// <param name="service">The IOrganizationService instance.</param>
/// <param name="entityLogicalName">The logical name of the table.</param>
/// <param name="messageName">The name of the message.</param>
/// <returns></returns>
public static bool IsMessageAvailable(
IOrganizationService service,
string entityLogicalName,
string messageName)
{
QueryExpression query = new("sdkmessagefilter")
{
ColumnSet = new ColumnSet("sdkmessagefilterid"),
Criteria = new FilterExpression(LogicalOperator.And)
{
Conditions = {
new ConditionExpression(
attributeName:"primaryobjecttypecode",
conditionOperator: ConditionOperator.Equal,
value: entityLogicalName)
}
},
LinkEntities = {
new LinkEntity(
linkFromEntityName:"sdkmessagefilter",
linkToEntityName:"sdkmessage",
linkFromAttributeName:"sdkmessageid",
linkToAttributeName:"sdkmessageid",
joinOperator: JoinOperator.Inner)
{
LinkCriteria = new FilterExpression(LogicalOperator.And){
Conditions = {
new ConditionExpression(
attributeName:"name",
conditionOperator: ConditionOperator.Equal,
value: messageName)
}
}
}
}
};
EntityCollection entityCollection = service.RetrieveMultiple(query);
return entityCollection.Entities.Count.Equals(1);
}
Pipelines de messages fusionnés
Chaque message d’opération en bloc a un message correspondant qui fonctionne sur des lignes individuelles : Create, Updateet Delete. Ces messages existent depuis longtemps et de nombreuses organisations ont une logique personnalisée qui dépend des événements qui se produisent lorsque ces messages sont utilisés.
Une exigence clé des messages d’opération en bloc est que les organisations ne doivent pas maintenir la logique personnalisée à deux emplacements. Pour avoir la même logique personnalisée et la conserver à un emplacement unique, Dataverse fusionne les pipelines de traitement des messages pour ces messages. Que signifie cette fusion ?
Lorsque vous utilisez un message d’opération en bloc, les événements respectifs
CreateetUpdatese produisent pour chaque instance d’entité dans le paramètreTargets. Tous les plug-ins existants ou autres gestionnaires d’événements pour les événements uniques correspondants continuent de fonctionner comme d’habitude. Vous n’avez pas besoin d’écrire de nouveaux plug-ins pour gérer les événements déclenchés par ces messages.Lorsque vous utilisez un message d’opération unique, l’événement d’opération en bloc respectif se produit avec entityCollection contenant une instanced’entité unique passée dans le
Targetsparamètre. Vous pouvez déplacer toute logique existante qui répond actuellement à des événements d’opération unique vers les événements d’opération en bloc plus efficaces et la logique est appliquée à la fois aux opérations uniques et multiples.
Avant l’introduction des messages d’opération en bloc, toute la logique personnalisée était appliquée aux messages d’opération unique. Cette logique continue d’être appliquée lorsque les applications clientes utilisent les messages d’opération en bloc. Pour les tables utilisées avec des opérations en bloc à volume élevé, déplacez toute logique synchrone d’événements de message unique vers des événements d’opération en bloc. Si vous introduisez une nouvelle logique, utilisez les événements d’opération en bloc plutôt que les événements d’opération unique.
Avertissement
Avec cette conception, la logique dupliquée peut potentiellement être appliquée à la fois aux versions uniques et multiples des événements. Dataverse n’essaie pas d’empêcher cela, car il ne peut pas connaître votre intention.
Il est de votre responsabilité de vous assurer que la même logique appliquée pour la version unique des événements est migrée vers la version multiple de l’événement et supprimée de la version unique de l’événement. Sinon, la logique s’applique deux fois.
Découvrez comment écrire des plug-ins pour CreateMultiple et UpdateMultiple.
Limitations
Gardez à l’esprit les limitations suivantes lorsque vous utilisez des messages d’opération en bloc.
Taille des messages et limites de temps
Pour les tables standard, vous obtenez de meilleures performances lorsque vous envoyez plus d’enregistrements avec chaque requête. Toutefois, la taille de la charge utile et le temps nécessaire pour traiter l’opération limite le nombre d’enregistrements que vous pouvez envoyer.
Limites de taille du message
Si vous inscrivez un plug-in pour un message, vous pouvez rencontrer l’erreur « Taille du message dépassée lors de l’envoi du contexte au bac à sable » lorsque la taille totale de la demande dépasse 116,85 Mo. Lorsque vous utilisez des messages d’opération en bloc, vous pouvez atteindre cette limite plus facilement, car vous envoyez des charges utiles plus volumineuses.
Cette erreur ne se produit pas si vous n’inscrivez pas de plug-in pour l’événement. Pour éviter l’erreur, désactivez les plug-ins ou envoyez votre demande à l’aide du BypassCustomPluginExecution paramètre facultatif.
Limites de temps
Si vous utilisez Dataverse ServiceClient, vous pouvez rencontrer cette erreur :
The request channel timed out attempting to send after 00:04:00.
Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding.
The time allotted to this operation may have been a portion of a longer timeout.
Le délai d’expiration par défaut défini à l’aide de ServiceClient est de quatre minutes, ce qui est long pour toute opération synchrone. Vous pouvez modifier cette valeur à l’aide de la propriété Static ServiceClient.MaxConnectionTimeout . Le délai d’expiration par défaut à l’aide de CrmServiceClient est de deux minutes.
Note
Avant d’augmenter les limites de temps, envisagez de réduire le nombre d’enregistrements que vous passez dans le Targets paramètre.
Non pris en charge pour une utilisation dans les plug-ins
Actuellement, Dataverse ne prend pas en charge l’utilisation de messages d’opération en bloc dans le code de plug-in. Pour plus d’informations, consultez Ne pas utiliser les types de requêtes par lots dans les plug-ins et les activités de flux de travail.
Cependant, vous devriez écrire des plug-ins pour les messages CreateMultiple et UpdateMultiple, comme décrit dans Écrire des plug-ins pour CreateMultiple et UpdateMultiple.
Résolution des erreurs courantes
Si vous rencontrez des erreurs lors de l’utilisation d’opérations en bloc, consultez les articles suivants :
Foire aux questions (FAQ)
Si vous n’avez pas trouvé de réponses à vos questions sur l’utilisation des messages d’opération en bloc dans cet article, utilisez le bouton au bas de cet article pour Envoyer et afficher les commentaires pour cette page. Vous avez besoin d’un compte GitHub pour soumettre des commentaires.
Les logiques Retrieve et RetrieveMultiple seront-elles fusionnées ?
Microsoft ne prévoit pas de modifier le comportement des messages Retrieve et RetrieveMultiple. Ces messages ont été des messages distincts depuis de nombreuses années, et les développeurs doivent toujours maintenir la logique pour eux séparément. Tenter de fusionner le pipeline de messages pour eux serait très problématique. En outre, évitez d’appliquer une logique personnalisée pour ces messages en raison de l’impact qu’ils peuvent avoir sur les performances.
Comment les limites d’API sont appliquées ?
Deux types de limites d’API s’appliquent. Les messages d’opération en bloc ne fournissent aucun moyen de contourner l’une ou l’autre de ces types.
Limites de la protection des services
Comme décrit dans Limites de l’API de protection des services, les limites ont trois facettes. Deux de ces limites sont évaluées sur une fenêtre glissante de cinq minutes et s’appliquent lors de l’utilisation de ces messages.
- Nombre de demandes : chaque message d’opération en bloc compte comme une demande unique qui s’accumule dans la limite de 6 000 demandes par utilisateur, par serveur, dans la fenêtre de 5 minutes. Étant donné que ces demandes regroupent des opérations individuelles, la probabilité d’atteindre cette limite est réduite.
- Temps d’exécution : étant donné que chaque demande de message d’opération en bloc prend généralement plus de temps, et si vous envoyez des demandes en parallèle, vous êtes plus susceptible d’atteindre la limite de temps d’exécution, qui est de 20 minutes par utilisateur, par serveur, dans la fenêtre de 5 minutes.
Limites des requêtes Power Platform (quota d’API)
Ces limites sont basées sur les modifications de données : opérations Create, Update et Delete. Chaque élément inclus dans le paramètre Targets d’une demande d’opération en bloc s’accumule dans cette limite.
En savoir plus sur les limites et allocations de demandes.
Voir aussi
Tableaux élastiques
Écrire des plug-ins pour CreateMultiple et UpdateMultiple
Exemple : SDK pour .NET - Utiliser des opérations en bloc
Exemple : Utilisation d'opérations en bloc d'API Web
Exemple : Plugs-ins CreateMultiple et UpdateMultiple
Utilisez les messages avec le SDK pour .NET
Optimiser les performances pour les opérations en bloc