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.
La conservation des données à long terme automatise le transfert de données de votre base de données transactionnelle Microsoft Dataverse vers un lac de données géré pour un archivage rentable. Commencez par configurer des tables pour la conservation à long terme. Ensuite, créez des stratégies de conservation qui définissent les données à archiver. Les exécutions de rétention planifiées transfèrent les lignes qui répondent aux critères.
Important
Pour utiliser toutes les fonctionnalités de rétention des données à long terme, vous devez répondre aux deux exigences décrites dans La vue d’ensemble de la conservation des données à long terme.
Récupérer les données conservées
Vous pouvez récupérer des données qui ont été conservées à l’aide de FetchXml et queryExpression .
En utilisant FetchXml, définissez la valeur de l’attribut de l’élément fetch elementdatasource sur "retained".
<fetch datasource="retained">
<entity name="account">
<attribute name="accountId" />
</entity>
</fetch>
Avec QueryExpression , définissez la propriété retained sur .
Note
Il n’existe actuellement aucun moyen de récupérer des données conservées à l’aide de l’API Web Dataverse avec une requête de style OData. Vous pouvez utiliser FetchXml avec l’API Web Dataverse.
Configurer une stratégie de conservation
Pour créer des stratégies de conservation, utilisez nos API, Maker Portal ou l’installation de la solution. L’exemple de code suivant illustre l’utilisation d’API pour créer une stratégie de conservation.
Le code suivant utilise le service d’organisation et la méthode IOrganizationService.Create(Entity) pour créer une stratégie de conservation qui conserve toutes les opportunités fermées et s’exécute chaque année. Les paramètres de périodicité valides sont DAILY, WEEKLY, MONTHLY et YEARLY. Pour n’exécuter la rétention qu’une seule fois, laissez la valeur de récurrence vide.
public void CreateRetentionConfig(IOrganizationService orgService)
{
Entity retentionConfig = new Entity("retentionconfig");
retentionConfig["retentionconfigid"] = Guid.NewGuid();
retentionConfig["entitylogicalname"] = "incident";
retentionConfig["name"] = "Retain all closed opportunities";
retentionConfig["uniquename"] = "ui_RetainAllClosedOpportunities";
retentionConfig["statecode"] = new OptionSetValue(0);
retentionConfig["statuscode"] = new OptionSetValue(10);
retentionConfig["criteria"] = "<fetch> " +
"<entity name=\"opportunity\"> " +
"<attribute name=\"name\" /> " +
"<attribute name=\"statecode\" />" +
"<attribute name=\"actualvalue\" />" +
"<attribute name=\"actualclosedate\" />" +
"<attribute name=\"customerid\" />" +
"<attribute name=\"opportunityid\" />" +
"<order attribute=\"actualclosedate\" descending=\"true\" />" +
"<filter type=\"and\">" +
"<filter type=\"or\">" +
"<condition attribute=\"statecode\" operator=\"eq\" value=\"1\" />" +
"<condition attribute=\"statecode\" operator=\"eq\" value=\"2\" />" +
"</filter>" +
"</filter>" +
"</entity></fetch>";
retentionConfig["starttime"] = DateTime.Parse("2024-05-01T00:00:00");
retentionConfig["recurrence"] = "FREQ=YEARLY;INTERVAL=1";
try
{
var retentionConfigId = orgService.Create(retentionConfig);
Console.WriteLine($"Retention policy created with Id : {retentionConfigId}");
}
catch (Exception ex)
{
throw new Exception($"Create retention policy failed: {ex.Message})", ex);
}
}
Le résultat de ce code est « Stratégie de conservation créée avec ID : c1a9e932-89f6-4f17-859c-bd2101683263 ».
Valider votre stratégie de conservation
Le processus de conservation à long terme déplace les données du stockage transactionnel Dataverse vers un lac de données géré. Vous ne pouvez plus exécuter d’opérations transactionnelles sur les données une fois qu’elles sont déplacées vers le lac de données. Il est important de vous assurer que vos stratégies de conservation sont correctes. Vous pouvez ajouter vos propres validations en enregistrant éventuellement un plug-in sur le message ValidateRetentionConfig.
class SampleValidateRetentionConfigPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var pluginContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var entityName = pluginContext.PrimaryEntityName;
if( pluginContext.InputParameters.TryGetValue("FetchXml", out var fetchXml) )
{
// Add custom validation against the Fetch XML.
}
else
{
throw new Exception("No critiera provided.");
}
}
}
Logique personnalisée pendant l’exécution de la conservation
La rétention à long terme est un processus asynchrone qui s’exécute chaque fois que vous configurez une stratégie de rétention. Elle effectue les opérations suivantes :
- Marquer les lignes (enregistrements) prêtes pour la conservation.
- Copier les lignes marquées dans le lac de données.
- Purger les lignes de la base de données source.
- Annuler les lignes marquées si la purge échoue.
Vous pouvez éventuellement enregistrer des plug-ins personnalisés à exécuter lorsque les lignes sont marquées pour la conservation, lorsque les lignes sont vidées à la source ou lorsque les lignes marquées pour la conservation sont restaurées. L’écriture de code de plug-in s’applique uniquement au SDK pour la programmation .NET. L’API web ne prend pas en charge le développement de plug-ins.
Logique personnalisée lorsqu’une ligne est marquée pour conservation
Dans le cadre du marquage des lignes à conserver, Dataverse appelle les messages BulkRetain et Retain. Vous pouvez ajouter une logique personnalisée en enregistrant un plug-in lors de l’exécution de ces messages. Par exemple, la logique personnalisée inclut le marquage d’autres lignes pour la rétention ou l’exécution de la validation avant que les lignes ne soient marquées pour la rétention.
Cet exemple de code montre un plug-in personnalisé exécuté lors de la conservation d’une seule ligne de table.
class SampleRetainPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var pluginContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var entityName = pluginContext.PrimaryEntityName;
if( pluginContext.InputParameters.TryGetValue("Target", out var _target) )
{
EntityReference target = (EntityReference)_target;
Console.WriteLine($"Request came for table : {target.Name} with id : {target.Id}");
// Add your logic for validation or additional operation.
// For example - you can call Retain on Additional row of another table.
}
else
{
throw new Exception("No target present.");
}
}
}
Pour une opération de conservation lors d’une restauration, écrivez votre plug-in sur le modèle de l’exemple précédent, sauf que vous devez l’enregistrer pour le message RollbackRetain.
Logique personnalisée lors de la conservation en bloc
Cet exemple de code montre une logique personnalisée lors de l’exécution de la dernière page d’une opération de message BulkRetain.
class SampleBulkRetainPlugin : IPlugin
{
// Send notification when bulk retain execution is done.
public void Execute(IServiceProvider serviceProvider)
{
var pluginContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var entityName = pluginContext.PrimaryEntityName;
if(pluginContext.OutputParameters != null
&& pluginContext.OutputParameters.TryGetValue("HasMoreRecords", out var _hasMoreRecords) )
{
if(!(bool)_hasMoreRecords)
{
Console.WriteLine("This is a last execution of this request.");
// SendNotifcation that retention for an entity is completed.
}
}
}
}
Logique personnalisée lorsqu’une ligne est supprimée en raison de la conservation
Dataverse exécute le PurgeRetainedContent message pour supprimer les lignes de données transactionnelles qu’elle a correctement déplacées vers le lac de données. Le message PurgeRetainedContent exécute en interne une opération de message Delete pour supprimer les lignes de table qu’il a réussi à déplacer.
Vous pouvez enregistrer un plug-in personnalisé dans le message PurgeRetainedContent si une logique personnalisée est nécessaire lors de l’opération de vidage au niveau de la table. Si vous le souhaitez, vous pouvez enregistrer un plug-in personnalisé sur le message Delete si vous devez exécuter du code lorsqu’une ligne est supprimée en raison d’une stratégie de rétention. Vous pouvez déterminer si la suppression s’est produite en raison de la rétention en vérifiant la propriété ParentContext du plug-in. La valeur de la propriété ParentContext pour l’opération de message Delete due à la conservation est « PurgeRetainedContent ».
Cet exemple de code empêche la purge d’une table lorsque les lignes ne sont pas prêtes à être purgées.
class SamplePurgeRetainedContentPlugin : IPlugin
{
// Block purge if all the rows are not validatd.
public void Execute(IServiceProvider serviceProvider)
{
var pluginContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var entityName = pluginContext.PrimaryEntityName;
if( pluginContext.InputParameters.TryGetValue("MaxVersionToPurge", out var _maxVersiontoPurge) )
{
long MaxVersionToPurge = (long)_maxVersiontoPurge;
var rowsToBePurged = GetToBePurgedRows(entityName, MaxVersionToPurge);
// Add custom validation to process rowsToBePurged.
}
}
public EntityCollection GetToBePurgedRows(string entityName, long maxVersionToPurge)
{
IOrganizationService organizationService; // Create OrgService.
QueryExpression queryExpression = new QueryExpression()
{
EntityName = entityName,
ColumnSet = new ColumnSet(new string[] { "versionnumber", "msft_datastate" })
};
queryExpression.Criteria.AddCondition("msft_datastate", ConditionOperator.Equal, 1);
queryExpression.Criteria.AddCondition("versionnumber", ConditionOperator.LessEqual, maxVersionToPurge);
var response = organizationService.RetrieveMultiple(queryExpression);
return response;
}
}
Cet exemple de code s’applique à l’opération de suppression liée à la stratégie de conservation.
class SampleDeletePlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
if (IsDeleteDueToRetention(serviceProvider))
{
// Write your code to handle delete during retention
}
else
{
// Write your code to handle normal delete without retention
}
}
private bool IsDeleteDueToRetention(IServiceProvider serviceProvider)
{
var currentContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
while (currentContext != null)
{
if (string.Equals(currentContext.MessageName, "PurgeRetainedContent"))
{
return true;
}
else
{
currentContext = currentContext.ParentContext;
}
}
return false;
}
}
Stratégie de conservation des requêtes et détails d’exécution
Le système stocke les détails de la stratégie de rétention dans la RetentionConfig table. Il stocke les détails d’exécution de la rétention dans les tables RetentionOperationDetail et RetentionOperation. Vous pouvez interroger ces tables pour obtenir la stratégie de rétention et les détails d’exécution.
Le code suivant fournit quelques exemples de FetchXML que vous pouvez utiliser pour interroger les lignes de la table de détails de rétention de date. FetchXML est un langage de requête propriétaire basé sur XML. Vous pouvez l’utiliser avec des requêtes basées sur le SDK à l’aide de FetchExpression et avec l’API web à l’aide de la chaîne de requête fetchXml.
Cet exemple de code montre une requête simple pour renvoyer toutes les stratégies de conservation actives pour une commande par e-mail par nom.
public EntityCollection GetActivePolicies(IOrganizationService orgService)
{
string fetchXml = @"
<fetch>
<entity name='retentionconfig'>
<attribute name='retentionconfigid' />
<attribute name='name' />
<attribute name='createdon' />
<attribute name='starttime' />
<attribute name='recurrence' />
<attribute name='entitylogicalname' />
<attribute name='criteria' />
<order attribute='name' descending='false' />
<filter type='and'>
<condition attribute='entitylogicalname' operator='eq' value='email' />
<condition attribute='statuscode' operator='eq' value='10' />
</filter>
</entity>
</fetch>";
var query = new FetchExpression(fetchXml);
EntityCollection results = orgService.RetrieveMultiple(query);
results.Entities.ToList().ForEach(x => {
Console.WriteLine(x.Attributes["name"]);
});
return(results);
}
Autres exemples de chaînes de requête FetchXML
Cet exemple de code illustre l’utilisation d’une instruction FetchXML pour récupérer toutes les stratégies de conservation suspendues pour un e-mail.
<fetch>
<entity name="retentionconfig">
<attribute name="retentionconfigid" />
<attribute name="name" />
<attribute name="createdon" />
<attribute name="starttime" />
<attribute name="recurrence" />
<attribute name="entitylogicalname" />
<attribute name="criteria" />
<order attribute="name" descending="false" />
<filter type="and">
<condition attribute="entitylogicalname" operator="eq" value="email" />
<condition attribute="statuscode" operator="eq" value="20" />
</filter>
</entity>
</fetch>
Cet exemple de code montre comment utiliser une instruction FetchXML pour récupérer toutes les opérations de conservation pour une stratégie de conservation.
<fetch>
<entity name="retentionoperation">
<attribute name="retentionoperationid" />
<attribute name="name" />
<attribute name="statuscode" />
<attribute name="statecode" />
<attribute name="starttime" />
<attribute name="rootentitylogicalname" />
<attribute name="endtime" />
<attribute name="criteria" />
<order attribute="name" descending="false" />
<filter type="and">
<condition
attribute="retentionconfigid"
operator="eq"
value="{35CC1317-20B7-4F4F-829D-5D9D5D77F763}" />
</filter>
</entity>
</fetch>
Cet exemple de code montre une instruction FetchXML qui récupère les détails d’une opération de conservation.
<fetch>
<entity name="retentionoperationdetail">
<attribute name="retentionoperationdetailid" />
<attribute name="name" />
<attribute name="createdon" />
<attribute name="retentionoperationid" />
<attribute name="retentioncount" />
<attribute name="isrootentity" />
<attribute name="failedcount" />
<attribute name="entitylogicalname" />
<order attribute="name" descending="false" />
<filter type="and">
<condition attribute="retentionoperationid" operator="eq" value="{35CC1317-20B7-4F4F-829D-5D9D5D77F763}"/>
</filter>
</entity>
</fetch>
Cet exemple de code illustre l’instruction FetchXML qui récupère les détails sur un échec survenu lors d’une opération de conservation.
<fetch>
<entity name="retentionfailuredetail">
<attribute name="retentionfailuredetailid" />
<attribute name="name" />
<attribute name="createdon" />
<attribute name="recordid" />
<attribute name="operation" />
<attribute name="message" />
<order attribute="name" descending="false" />
<filter type="and">
<condition attribute="operationid" operator="eq" value="35CC1317-20B7-4F4F-829D-5D9D5D77F763" />
</filter>
</entity>
</fetch>
Voir aussi
Gérer les stratégies de conservation des données
Afficher les données conservées à long terme
Supprimer en bloc des données
Utiliser l'API Web Microsoft Dataverse