Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
A retenção de dados de longo prazo automatiza a transferência de dados de seu banco de dados transacional Microsoft Dataverse para um data lake gerenciado para armazenamento de arquivamento econômico. Comece configurando tabelas para retenção de longo prazo. Em seguida, crie políticas de retenção que definem os dados a serem arquivados. As execuções de retenção agendadas transferem as linhas que correspondem aos critérios.
Importante
Para usar todos os recursos de retenção de dados de longo prazo, você deve atender aos dois requisitos descritos na visão geral da retenção de dados de longo prazo do Dataverse.
Recuperar dados retidos
Você pode recuperar dados que foram retidos usando FetchXml e QueryExpression .
Ao usar FetchXml, defina o valor do atributo do elemento fetchdatasource como "retained".
<fetch datasource="retained">
<entity name="account">
<attribute name="accountId" />
</entity>
</fetch>
Usando QueryExpression , defina a propriedade QueryExpression.DataSource como retained.
Note
No momento, não há como recuperar dados retidos usando a API Web do Dataverse com uma consulta no estilo OData. Você pode usar FetchXml com a API Web do Dataverse.
Configurar uma política de retenção
Para criar políticas de retenção, use nossas APIs, o portal do criador ou a instalação da solução. O exemplo de código a seguir demonstra o uso de APIs para criar uma política de retenção.
O código a seguir usa o serviço Organização e o método IOrganizationService.Create(Entity) para criar uma política de retenção que retém todas as oportunidades fechadas e é executada anualmente. Os parâmetros de recorrência válidos são DAILY, WEEKLYe MONTHLYYEARLY. Para executar a retenção apenas uma vez, deixe o valor de recorrência em branco.
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);
}
}
A saída desse código é "Política de retenção criada com id: c1a9e932-89f6-4f17-859c-bd2101683263".
Validar sua política de retenção
O processo de retenção de longo prazo move dados do armazenamento transacional do Dataverse para um data lake gerenciado. Você não pode mais executar operações transacionais nos dados depois que eles são movidos para o data lake. É importante garantir que suas políticas de retenção estejam corretas. Você pode adicionar suas próprias validações, registrando opcionalmente um plug-in personalizado na ValidateRetentionConfig mensagem.
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.");
}
}
}
Lógica personalizada durante a execução da retenção
A retenção de longo prazo é um processo assíncrono que é executado sempre que você configura uma política de retenção. Ele executa as seguintes operações:
- Marque linhas (registros) como prontas para retenção.
- Copie linhas marcadas para o data lake.
- Limpar linhas do banco de dados de origem.
- Reverta as linhas marcadas se a purga falhar.
Você também pode registrar plug-ins personalizados a serem executados quando as linhas estiverem sendo marcadas para retenção, quando as linhas estiverem sendo limpas na origem ou quando as linhas marcadas para retenção forem revertidas. Escrever código de plug-in aplica-se apenas ao SDK para programação .NET. A API Web não dá suporte ao desenvolvimento de plug-in.
Lógica personalizada quando a linha é marcada para ser retida
Ao marcar linhas para retenção, o Dataverse invoca as mensagens BulkRetain e Retain. Você pode adicionar lógica personalizada registrando um plug-in na execução dessas mensagens. Exemplos de lógica personalizada incluem marcar mais linhas para retenção ou executar a validação antes que as linhas sejam marcadas para retenção.
Este exemplo de código mostra um plug-in personalizado executado durante a retenção de uma única linha de tabela.
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.");
}
}
}
Para uma operação de retenção de reversão, grave o plug-in de maneira semelhante ao exemplo anterior, mas o registre na mensagem RollbackRetain.
Lógica personalizada para retenção em massa
Este exemplo de código demonstra uma lógica personalizada durante a execução da última página de uma operação de mensagem 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.
}
}
}
}
Lógica personalizada quando a linha é excluída por retenção
O Dataverse executa a mensagem PurgeRetainedContent para excluir as linhas de dados transacionais que foram movidas com êxito para o data lake. A PurgeRetainedContent mensagem executa internamente uma Delete operação de mensagem para excluir as linhas de tabela que ela moveu com êxito.
Você pode registrar um plug-in personalizado na mensagem PurgeRetainedContent se precisar de lógica personalizada durante a operação de expurgo em nível de tabela. Opcionalmente, você poderá registrar um plug-in personalizado na Delete mensagem se precisar invocar o código quando uma linha for excluída devido à retenção. Você pode determinar se a exclusão ocorreu devido à retenção verificando a propriedade ParentContext do plug-in. O valor da propriedade ParentContext da operação de mensagem Delete, devido à retenção, é "PurgeRetainedContent".
Este exemplo de código bloqueia a limpeza em uma tabela quando as linhas não estão prontas para limpeza.
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;
}
}
Este exemplo de código aplica-se à operação de exclusão por retenção.
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;
}
}
Política de retenção de consultas e detalhes de execução
O sistema armazena detalhes da política de retenção na RetentionConfig tabela. Ele armazena detalhes da execução de retenção nas tabelas RetentionOperationDetail e RetentionOperation. Você pode consultar essas tabelas para obter a política de retenção e os detalhes de execução.
O código a seguir fornece alguns exemplos de FetchXML que você pode usar para consultar as linhas da tabela de detalhes de retenção de data. FetchXML é uma linguagem de consulta baseada em XML proprietária. Você pode usá-lo com consultas baseadas em SDK usando FetchExpression e pela API Web usando a fetchXml cadeia de caracteres de consulta.
Este exemplo de código mostra uma consulta simples para retornar todas as políticas de retenção ativas para um pedido de email por nome.
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);
}
Mais exemplos de cadeias de caracteres de consulta FetchXML
Este exemplo de código ilustra o uso de uma instrução FetchXML para recuperar todas as políticas de retenção pausadas para um email.
<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>
Este exemplo de código mostra como usar uma instrução FetchXML para recuperar todas as operações de retenção para uma política de retenção.
<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>
Este exemplo de código mostra uma instrução FetchXML que recupera detalhes de uma operação de retenção.
<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>
Este exemplo de código ilustra a instrução FetchXML que recupera detalhes sobre uma falha que ocorreu durante uma operação de retenção.
<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>
Consulte também
Gerenciar políticas de retenção de dados
Exibir dados retidos a longo prazo
Excluir dados em massa
Usar a API Web do Microsoft Dataverse