Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Langfristige Datenaufbewahrung automatisiert den Transfer von Daten aus Ihrer Microsoft Dataverse-Transaktionsdatenbank zu einem verwalteten Data Lake für kosteneffiziente Archivspeicherung. Beginnen Sie mit dem Konfigurieren von Tabellen für Langzeitaufbewahrung. Erstellen Sie dann Aufbewahrungsrichtlinien, die die zu archivierenden Daten definieren. Geplante Aufbewahrungsläufe übertragen Zeilen, die den Kriterien entsprechen.
Wichtig
Um alle langfristigen Datenaufbewahrungsfeatures zu verwenden, müssen Sie beide Anforderungen erfüllen, die in der Übersicht über die langfristige Datenaufbewahrung von Dataverse beschrieben sind.
Beibehaltene Daten abrufen
Sie können Daten abrufen, die mithilfe von FetchXml und QueryExpression aufbewahrt wurden.
Legen Sie mithilfe von FetchXml den Attributwert des fetch-Elementsdatasource auf "retained".
<fetch datasource="retained">
<entity name="account">
<attribute name="accountId" />
</entity>
</fetch>
Legen Sie mithilfe von QueryExpression die QueryExpression.DataSource-Eigenschaft auf retained.
Anmerkung
Es gibt derzeit keine Möglichkeit, aufbewahrte Daten mithilfe der Dataverse-Web-API mit einer OData-Formatabfrage abzurufen. Sie können FetchXml mit der Dataverse-Web-API verwenden.
Eine Aufbewahrungsrichtlinie einrichten
Verwenden Sie zum Erstellen von Aufbewahrungsrichtlinien unsere APIs, das Maker Portal oder die Lösungsinstallation. Das folgende Codebeispiel demonstriert die Verwendung von APIs zur Erstellung eines Aufbewahrungsrichtlinie.
Der folgende Code verwendet den Organisationsdienst und die IOrganizationService.Create(Entity)-Methode, um eine Aufbewahrungsrichtlinie zu erstellen, die alle geschlossenen Verkaufschancen aufbewahrt und jährlich ausgeführt wird. Gültige Wiederholungsparameter sind DAILY, WEEKLY, MONTHLY und YEARLY. Um die Aufbewahrung nur einmal auszuführen, setzen Sie den Wiederholungswert auf leer.
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);
}
}
Die Ausgabe dieses Codes lautet „Aufbewahrungsrichtlinie erstellt mit Id : c1a9e932-89f6-4f17-859c-bd2101683263“.
Überprüfen Sie Ihre Aufbewahrungsrichtlinie
Der Prozess der Langzeitaufbewahrung verschiebt Daten vom Dataverse-Transaktionsspeicher in einen verwalteten Data Lake. Sie können keine Transaktionsvorgänge mehr auf den Daten ausführen, nachdem diese in den Data Lake verschoben wurden. Es ist wichtig, sicherzustellen, dass Ihre Aufbewahrungsrichtlinien korrekt sind. Sie können Ihre eigenen Validierungen hinzufügen, indem Sie optional ein angepasstes Plug-in für die Nachricht ValidateRetentionConfig registrieren.
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.");
}
}
}
Angepasste Logik, wenn die Speicherung ausgeführt wird
Die langfristige Aufbewahrung ist ein asynchroner Prozess, der immer ausgeführt wird, wenn Sie eine Aufbewahrungsrichtlinie einrichten. Es werden die folgenden Vorgänge ausgeführt:
- Markieren Sie Zeilen (Datensätze), die für die Aufbewahrung bereit sind.
- Kopieren Sie die markierten Zeilen in den Data Lake.
- Löschen Sie Zeilen aus der Quelldatenbank.
- Führen Sie ein Rollback der markierten Zeilen durch, wenn die Bereinigung fehlschlägt.
Sie können optional benutzerdefinierte Plug-Ins registrieren, die ausgeführt werden, wenn Zeilen zur Aufbewahrung markiert werden, wenn Zeilen an der Quelle gelöscht werden oder wenn für zur Aufbewahrung markierte Zeilen ein Rollback durchgeführt wird. Das Schreiben von Plug-in Code gilt nur für SDK für .NET Programmierung. Die Web-API unterstützt nicht die Plug-In-Entwicklung.
Angepasste Logik, wenn eine Zeile zur Speicherung markiert wird
Im Rahmen der Markierung von Zeilen zur Aufbewahrung ruft Dataverse die Nachrichten BulkRetain und Retain auf. Sie können benutzerdefinierte Logik hinzufügen, indem Sie bei der Ausführung dieser Nachrichten ein Plug-In registrieren. Beispiele für benutzerdefinierte Logik sind das Markieren weiterer Zeilen für die Aufbewahrung oder das Durchführen einer Überprüfung, bevor Zeilen für die Aufbewahrung markiert werden.
Dieses Codebeispiel zeigt ein benutzerdefiniertes Plug-In, das während der Aufbewahrung einer einzelnen Tabellenzeile ausgeführt wird.
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.");
}
}
}
Schreiben Sie für einen Rollback-Beibehaltungsvorgang Ihr Plug-In wie im vorhergehenden Beispiel, außer dass Sie es für die Nachricht RollbackRetain registrieren.
Benutzerdefinierte Logik für Massenaufbewahrung
In diesem Codebeispiel wird die benutzerdefinierte Logik für die letzte Seitenausführung eines BulkRetain Nachrichtenvorgangs veranschaulicht.
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.
}
}
}
}
Benutzerdefinierte Logik, wenn eine Zeile aufgrund einer Aufbewahrung gelöscht wird
Dataverse führt die PurgeRetainedContent-Nachricht aus, um die Zeilen mit Transaktionsdaten zu löschen, die Dataverse erfolgreich in den Data Lake verschoben hat. Die PurgeRetainedContent Nachricht führt intern einen Delete Nachrichtenvorgang aus, um die Tabellenzeilen zu löschen, die sie erfolgreich verschoben haben.
Sie können ein benutzerdefiniertes Plug-In für die PurgeRetainedContent-Nachricht registrieren, wenn Sie während des Bereinigungsvorgangs auf Tabellenebene eine benutzerdefinierte Logik benötigen. Optional können Sie ein benutzerdefiniertes Plug-In für die Delete-Nachricht registrieren, wenn Sie Code aufrufen müssen, wenn eine Zeile aufgrund der Aufbewahrung gelöscht wird. Sie können ermitteln, ob der Löschvorgang aufgrund der Aufbewahrung erfolgt ist, indem Sie die ParentContext-Eigenschaft des Plug-Ins überprüfen. Der Eigenschaftswert ParentContext für den Nachrichtenvorgang Delete aufgrund der Aufbewahrung ist „PurgeRetainedContent.“
In diesem Codebeispiel wird die Bereinigung einer Tabelle blockiert, wenn Zeilen nicht zum Löschen bereit sind.
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;
}
}
Dieses Codebeispiel gilt für den Löschvorgang aufgrund der Aufbewahrung.
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;
}
}
Abfragen von Aufbewahrungsrichtlinien und Ausführungsdetails
Das System speichert Details zur Aufbewahrungsrichtlinie in der RetentionConfig Tabelle. Es speichert Details zur Aufbewahrungsausführung in den RetentionOperation und RetentionOperationDetail Tabellen. Sie können diese Tabellen abfragen, um die Aufbewahrungsrichtlinie und Details zur Ausführung zu erhalten.
Der folgende Code enthält einige Beispiele für FetchXML, mit denen Sie die Zeilen der Datumsaufbewahrungsdetailseite abfragen können. FetchXML ist eine proprietäre XML-basierte Abfragesprache. Sie können es mit SDK-basierten Abfragen unter Verwendung von FetchExpression und mit der Web-API unter Verwendung der Abfragezeichenfolge fetchXml verwenden.
Dieses Codebeispiel zeigt eine einfache Abfrage zum Zurückgeben aller aktiven Aufbewahrungsrichtlinien für eine E-Mail-Bestellung nach Namen.
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);
}
Weitere Beispiele für FetchXML-Abfragezeichenfolgen
Dieses Codebeispiel veranschaulicht die Verwendung einer FetchXML-Anweisung zum Abrufen aller angehaltenen Aufbewahrungsrichtlinien für eine 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>
Dieses Codebeispiel zeigt, wie Sie mit einer FetchXML-Anweisung alle Aufbewahrungsvorgänge für eine Aufbewahrungsrichtlinie abrufen.
<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>
Dieses Codebeispiel zeigt eine FetchXML-Anweisung, die Details für einen Aufbewahrungsvorgang abruft.
<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>
Dieses Codebeispiel veranschaulicht die FetchXML-Anweisung, die Details zu einem Fehler abruft, der während eines Aufbewahrungsvorgangs aufgetreten ist.
<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>
Siehe auch
Verwaltung von Richtlinien zur Datenaufbewahrung
Langfristig gespeicherte Daten anzeigen
Löschen von Datensätzen in einem Massenvorgang
Verwenden der Microsoft Dataverse-Web-API