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.
Note
Les messages CreateMultiple et UpdateMultiple sont en cours de déploiement. Toutes les tables qui prennent en charge Create et Update prendront éventuellement en charge CreateMultiple et UpdateMultiple, mais certaines tables peuvent ne pas encore les prendre en charge.
En savoir plus sur les messages d’opération en bloc
Vous devez écrire des plug-ins pour les messages CreateMultiple et les tables UpdateMultiple où il est nécessaire de créer ou mettre à jour des enregistrements en bloc, ou lorsqu'il est important d'optimiser les performances pour la création et la mise à jour d’un grand nombre d’enregistrements. Environ chaque table qui stocke les données métier peut avoir besoin d’être créée ou mise à jour en bloc.
Si vous avez des plug-ins existants pour les messages Create et Update concernant des tables comme celles-ci, vous devez les migrer pour utiliser CreateMultiple et UpdateMultiple à la place.
La mise à jour des plug-ins est-elle requise ?
Vous n’êtes pas obligé de migrer vos plug-ins pour qu’ils utilisent CreateMultiple et UpdateMultiple au lieu de Create et Update. Votre logique continue d’être appliquée lorsque les applications utilisent CreateMultiple ou UpdateMultiple. Il n’est pas nécessaire de migrer vos plug-ins, car le pipeline de traitement des messages Dataverse fusionne la logique des plug-ins écrits pour la version unique ou multiple de ces messages.
Toutefois, seuls les plug-ins écrits pour la version multiple de ces messages obtiennent une amélioration significative des performances. Au fil du temps, à mesure que d'autres développeurs choisissent d'optimiser les performances en utilisant les messages CreateMultiple et UpdateMultiple, nous nous attendons à ce que l'écriture de plug-ins pour plusieurs opérations devienne la norme. Les plug-ins écrits pour les opérations uniques seront l’exception.
Qu’est-ce qui est différent ?
Voici quelques-unes des différences que vous devez gérer lorsque vous migrez vos plug-ins vers les messages CreateMultiple et UpdateMultiple.
Cibles au lieu de Cible
Les versions multiples de ces messages ont un paramètre Targets qui est une EntityCollection, plutôt qu’un paramètre Target qui est une entité unique. Votre code de plug-in doit parcourir les entités de la collection et appliquer la logique à chacune d’elles.
Images d’entité
Les images d’entité qui sont configurées dans l’enregistrement d’étape pour vos plug-ins sont un tableau de EntityImageCollection. Ces images d’entité sont disponibles uniquement lorsque vous utilisez l’interface IPluginExecutionContext4, qui fournit les propriétés PreEntityImagesCollection et PostEntityImagesCollection . Ces tableaux fournissent l’accès aux mêmes images d’entité dans un tableau synchronisé avec EntityCollection.
Si vous utilisez la PluginBase classe qui est la norme lors de l’initialisation des projets de plug-in à l’aide des outils Power Platform, alors dans le fichier PluginBase.cs, vous devez remplacer toutes les instances de IPluginExecutionContext par IPluginExecutionContext4 afin que ces collections d’images d’entité soient disponibles pour votre plug-in.
Important
Lorsque vous configurez des images d’entité pour les étapes de plug-in concernant CreateMultiple et UpdateMultiple, il est important de sélectionner soigneusement les données des colonnes à inclure. Ne sélectionnez pas l’option par défaut de toutes les colonnes. Ces données sont multipliées par le nombre d’entités passées dans le Targets paramètre et contribuent à la taille totale du message envoyé au bac à sable. Vous pouvez atteindre la limite de taille des messages.
Filtres d’attributs
Pour un plug-in enregistré sur Update ou UpdateMultiple, vous pouvez spécifier des attributs de filtrage à l’étape de l’inscription.
- Avec
Update, le plug-in s’exécute uniquement lorsque l’un des attributs sélectionnés est inclus avec l’entitéTargeten cours de mise à jour. - Avec
UpdateMultiple, le plug-in s’exécute quand l’un des attributs sélectionnés est inclus dans l’une des entités duTargetsparamètre.
Important
Pour UpdateMultiple, vous ne pouvez pas supposer que chaque entité du paramètre Targets contient des attributs qui sont utilisés dans un filtre.
Example
Les exemples suivants, l'un avec une logique de base pour Update et l'autre avec la logique pour UpdateMultiple, accèdent aux images d'entité associées à l'étape.
Cet exemple met à jour l'attribut sample_description avec des informations sur si la valeur sample_name a changé. Il fait référence à une image d’entité nommée example_preimage qui a été enregistrée avec l’étape.
// Verify input parameters
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity entity)
{
// Verify expected entity image from step registration
if (context.PreEntityImages.TryGetValue("example_preimage", out Entity preImage))
{
bool entityContainsSampleName = entity.Contains("sample_name");
bool entityImageContainsSampleName = preImage.Contains("sample_name");
bool entityImageContainsSampleDescription = preImage.Contains("sample_description");
if (entityContainsSampleName && entityImageContainsSampleName && entityImageContainsSampleDescription)
{
// Verify that the entity 'sample_name' values are different
if (entity["sample_name"] != preImage["sample_name"])
{
string newName = (string)entity["sample_name"];
string oldName = (string)preImage["sample_name"];
string message = $"\\r\\n - 'sample_name' changed from '{oldName}' to '{newName}'.";
// If the 'sample_description' is included in the update, do not overwrite it, just append to it.
if (entity.Contains("sample_description"))
{
entity["sample_description"] = entity["sample_description"] += message;
}
else // The sample description is not included in the update, overwrite with current value + addition.
{
entity["sample_description"] = preImage["sample_description"] += message;
}
// Success:
localPluginContext.Trace($"Appended to 'sample_description': \"{message}\" ");
}
else
{
localPluginContext.Trace($"Expected entity and preImage 'sample_name' values to be different. Both are {entity["sample_name"]}");
}
}
else
{
if (!entityContainsSampleName)
localPluginContext.Trace("Expected entity sample_name attribute not found.");
if (!entityImageContainsSampleName)
localPluginContext.Trace("Expected preImage entity sample_name attribute not found.");
if (!entityImageContainsSampleDescription)
localPluginContext.Trace("Expected preImage entity sample_description attribute not found.");
}
}
else
{
localPluginContext.Trace($"Expected PreEntityImage: 'example_preimage' not found.");
}
}
else
{
if (!context.InputParameters.Contains("Target"))
localPluginContext.Trace($"Expected InputParameter: 'Target' not found.");
if (!(context.InputParameters["Target"] is Entity))
localPluginContext.Trace($"Expected InputParameter: 'Target' is not Entity.");
}
Gestion des exceptions
Toutes les erreurs qui se produisent dans vos plug-ins doivent être retournées à l’aide de InvalidPluginExecutionException. Lorsque votre plug-in lève une exception pour les étapes enregistrées sur les messages CreateMultiple et UpdateMultiple, il doit identifier l’enregistrement à l’origine de l’échec du plug-in. Pour capturer ces informations, vous devez utiliser l’un de ces constructeurs suivants :
- InvalidPluginExecutionException(String, Dictionary<String,String>)
- InvalidPluginExecutionException(OperationStatus, String, Dictionary<String,String>)
Ces constructeurs vous permettent d’ajouter des valeurs à la propriété InvalidPluginExecutionException.ExceptionDetails , qui ne peut pas être définie directement.
Utilisez le paramètre du Dictionary<String,String>exceptionDetails constructeur pour inclure des informations sur l’enregistrement ayant échoué et d’autres informations pertinentes.
Définir les détails de l’exception
Pour le UpdateMultiple message, votre code effectue une itération dans la propriété EntityCollectionTargets et applique la logique à chaque entité. Si une défaillance se produit, vous pouvez transmettre l’ID de l’enregistrement au InvalidPluginExecutionException constructeur de la manière suivante :
// in plugin code
foreach (Entity entity in Targets)
{
// [...] When an error occurs:
var exceptionDetails = new Dictionary<string, string>();
exceptionDetails.Add("failedRecordId", (string)entity.Id);
throw new InvalidPluginExecutionException("This is an error message.", exceptionDetails);
}
Ajoutez toute autre information pertinente à l’échec sous forme de paires clé-valeur de chaîne au paramètre exceptionDetails.
Pour CreateMultiple, nous vous recommandons de ne pas définir la valeur de clé primaire pour chaque enregistrement. Dans la plupart des cas, vous devez autoriser le système à définir la valeur de clé primaire pour vous, car les valeurs générées par le système sont optimisées pour des performances optimales.
Dans les cas où la valeur de clé primaire n’est pas définie, s’il n’existe aucun autre identificateur unique, vous devrez peut-être retourner l’index de l’enregistrement ayant échoué dans le paramètre EntityCollectionTargets , ou une combinaison de valeurs qui identifient de manière unique l’enregistrement qui échoue. Par exemple, une clé appelée failedRecordIndex, qui indique l'emplacement de l’enregistrement dans le EntityCollection, ou tout autre identificateur unique utile, peut être ajoutée à exceptionDetails pour faciliter la résolution de l’échec.
Obtenir les détails de l’exception
Lorsque vous incluez des détails sur l’opération défaillante dans la propriété InvalidPluginExecutionException.ExceptionDetails , l’application cliente peut les obtenir à partir de la propriété OrganizationServiceFault.ErrorDetails via faultException<OrganizationServiceFault>. Propriété Detail . Le code suivant montre comment :
try
{
// xMultiple request that triggers your plugin
}
catch (FaultException<OrganizationServiceFault> ex)
{
ex.Detail.ErrorDetails.TryGetValue("failedRecordId", out object failedRecordId);
}
Si l’application cliente utilise l’API web, elle peut obtenir plus de détails sur les erreurs en définissant l’en-tête de Prefer: odata.include-annotations="*" requête.
Remplacer les plug-ins à opération unique dans les solutions
Lorsque vous déployez des enregistrements d’étapes de plug-in dans des solutions, il n'existe aucun moyen de forcer la désactivation ou la suppression d'un enregistrement d'étape. Cela rend le remplacement de la logique d’une seule opération vers un plug-in d’opération multiple un défi.
Lorsque vous déployez une nouvelle étape de plug-in dans une solution pour CreateMultiple ou UpdateMultiple qui remplace une étape de plug-in pour Create ou Update, vous souhaitez réduire la période pendant laquelle aucune logique ni logique en double n'est appliquée. Vous pouvez désactiver manuellement les étapes pour Create ou Update avant ou après l’installation de la solution. Si vous désactivez avant, il existe une période pendant laquelle aucune logique n’est appliquée. Si vous désactivez après, il y a une période pendant laquelle la logique dupliquée est appliquée. Dans les deux cas, l’organisation peut nécessiter un temps d’arrêt planifié pour garantir que la logique est appliquée de manière cohérente.
Pour réduire la durée de l’une de ces conditions, nous vous recommandons d’inclure une logique pour désactiver les étapes qui sont remplacées par le déploiement des nouveaux plug-ins avec package Deployer. Package Deployer offre la possibilité d’exécuter du code personnalisé avant, pendant et après l’importation du package dans un environnement. Utilisez ce code pour désactiver les enregistrements d'étapes existants.
Voir aussi
Exemple : plugs-ins CreateMultiple et UpdateMultiple
Messages d’opération en bloc
Exemple : opérations en bloc SDK pour .NET
Optimiser les performances des opérations en bloc