使用代码还原已删除的记录

[本文是预发行文档,可能会有所更改。]

有时人们删除不应删除的记录。 管理员可以启用已删除的记录保留,以便他们可以在指定的时间段内还原已删除的记录。 了解管理员如何还原已删除的记录

启用已删除的记录保留后,开发人员可以使用 Restore 该消息在指定时间段之前还原已删除的记录。 时间段最多可为 30 天。

检索可还原的已删除记录

若要检索可还原的已删除记录,请将查询的数据源设置为“”。bin 以下示例最多返回三个已删除的帐户记录。

使用 SDK 时,可以使用 FetchXmlQueryExpression 检索数据。

使用 FetchXml 检索数据时,检索记录时,将 fetch 元素datasource 属性设置为“bin”。

static EntityCollection GetDeletedAccountRecordsFetchXml(IOrganizationService service) {

   string queryString = @"<fetch top='3' datasource='bin'>
                     <entity name='account'>
                        <attribute name='name' />
                     </entity>
                     </fetch>";
   
   FetchExpression query = new(queryString);

   return service.RetrieveMultiple(query);
}

使用 QueryExpression 检索数据时,检索记录时,请将 QueryExpression.DataSource 属性设置为“bin”。

static EntityCollection GetDeletedAccountRecordsQueryExpression(IOrganizationService service) {

   QueryExpression query = new("account") { 
         ColumnSet = new ColumnSet("name"),
         DataSource = "bin",
         TopCount = 3
   };

   return service.RetrieveMultiple(query);
}

还原已删除的记录

使用该 Restore 消息还原已删除的记录。 该 Target 参数不是对已删除记录的引用。 这是一个完整的记录,因此可以在还原记录时设置列值。 除非您在 Restore 操作期间通过设置值进行覆盖,否则所有原始列值均将被恢复。

注释

目前,只能使用主键值还原记录。 不能使用备用密钥还原记录。

您恢复已删除记录的方式取决于您是在使用 .NET SDK 还是 Web API。

如何使用 SDK for .NET 还原记录取决于是使用 pac modelbuilder 生成早期绑定类型还是使用后期绑定样式。

了解如何使用 .NET SDK 进行晚绑定和早绑定编程

早期绑定示例

静态RestoreAccountRecordEarlyBound方法使用RestoreRequest<T>生成的Account类。

/// <summary>
/// Restores an account record
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="accountId">The ID of the deleted account record.</param>
/// <param name="originalName">The original name value for the account record.</param>
/// <returns>The ID of the restored account</returns>
static Guid RestoreAccountRecordEarlyBound(
    IOrganizationService service, 
    Guid accountId,
    string originalName)
{
    Account accountToRestore = new()
    {
        Id = accountId,
        // Appending '(Restored)' to the original name
        // to demonstrate overwriting a value.
        Name = originalName + " (Restored)"
    };

    RestoreRequest<Account> request = new()
    {
        Target = accountToRestore
    };

    var response = (RestoreResponse)service.Execute(request);
    return response.id;
}

后期绑定示例

静态 RestoreAccountRecordLateBound 方法使用 OrganizationRequest 类调用 Restore 消息,并设置 Target 参数。

/// <summary>
/// Restores an account record
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="accountId">The ID of the deleted account record.</param>
/// <param name="originalName">The original name value for the account record.</param>
/// <returns>The ID of the restored account</returns>
static Guid RestoreAccountRecordLateBound(
   IOrganizationService service,
   Guid accountId,
   string originalName)
{
   Entity accountToRestore = new("account", accountId)
   {
         Attributes = {
            // Appending '(Restored)' to the original name
            // to demonstrate overwriting a value.
            {"name", originalName + " (Restored)"}
         }
   };

   OrganizationRequest request = new("Restore")
   {
         Parameters = {
            { "Target", accountToRestore }
         }
   };

   OrganizationResponse response = service.Execute(request);

   return (Guid)response.Results["id"];
}

将消息与用于 .NET 的 SDK 配合使用

还原记录时的最佳做法

还原记录时避免以下问题:

如果某些相关记录引用了级联关系已删除的记录,则恢复操作将失败。 为避免此问题,在尝试还原主记录前,始终先恢复当前记录删除之前关联的记录。

名称:RefCannotBeRestoredRecycleBinNotFound
代码:0x80049959
编号: -2147182247
消息:Entity with id '<Guid Value>' and logical name '<Entity.LogicalName>' does not exist. We cannot restore the reference '<Referred Primary Key Name>' that must be restored as part of this Restore call. ValueToBeRestored: <Guid Value>, ReferencedEntityName: <Referenced Entity Name>, AttributeName: <Referred Attribute Name>

创建记录时不要指定主键值

始终让 Dataverse 在创建记录时设置主键。 如果创建与已删除记录具有相同主键值的新记录,则无法还原已删除的记录。 如果要还原已删除的记录,请先删除新记录。

名称:DuplicateExceptionRestoreRecycleBin
代码:0x80044a02
编号: -2147182279
消息:Please delete the existing conflicting record '<Entity Platform Name>' with primary key '<Primary Key Name>' and primary key value '<Primary Key Value>' before attempting restore.

具有匹配备用键值的记录阻止还原

如果创建与已删除记录具有相同备用键列值的记录,则无法还原已删除的记录。 如果要还原已删除的记录,请先删除新记录。

名称:DuplicateExceptionEntityKeyRestoreRecycleBin
代码:0x80049929
编号: -2147182295
消息:Duplicate entity key preventing restore of record '<Entity Platform Name>' with primary key '<Primary Key Name>' and primary key value '<Primary Key Value>'. See inner exception for entity key details.

未还原使用已删除“选择”选项的记录

如果删除了选项集选项,并且该选项在已删除的记录中使用,则无法还原该记录,因为该选项现在无效。 在删除选项集选项之前,请检查是否没有记录使用该选项,包括已删除的记录。

名称:PicklistValueOutOfRangeRecycleBin
代码:0x80049949
编号: -2147182263
消息:Picklist value not valid, please add the invalid value back to the picklist before restoring record

删除时发生主键冲突

如果具有相同主键的记录已存在,则不执行任何操作。 若要强制记录所有已删除项,请使用适用于 Microsoft Dynamics CRM 的 OrgDBOrgSettings 工具设置 DoNotEnforcePrimaryKeyOrgSettingRecycleBin 设置

启用此设置后,可能会收到以下错误:

名称:DuplicateExceptionRestoreRecycleBin
代码:0x80049939
编号: -2147182279
消息:A record that has the attribute values Deleted Object already exists on Delete.

检测哪些表已启用已删除记录保留功能

启用此功能之前, 删除的记录保留配置(RecycleBinConfig)表 没有行。

随着时间的推移,大多数表都将支持已删除记录保留功能。 解决方案组件虚拟表弹性表不支持已删除记录保留功能。 某些当前未启用的表可能稍后启用(例如,包含超过 600 列的表)。 有关不支持此功能的表的列表,请参阅 当前不支持的表

还可以 为环境禁用删除记录保留功能。 如果未为表启用已删除的记录保留,则找不到 有资格还原的任何记录。 您可以查询 Dataverse 以确定某张表是否已启用已删除记录保留功能。

已启用已删除记录保留功能的表在 RecycleBinConfig 表中拥有一行,其中 statecode 处于活动状态且 isreadyforrecyclebin 为 true。 该 RecycleBinConfig 表不包含表的名称,但引用 实体表中 的一行,其中 logicalname 该列包含表的 LogicalName

使用以下 FetchXml 查询来检测哪些表已启用已删除记录保留功能:

<fetch>
  <entity name='recyclebinconfig'>
    <filter type='and'>
      <condition attribute='statecode'
        operator='eq'
        value='0' />
      <condition attribute='isreadyforrecyclebin'
        operator='eq'
        value='1' />
    </filter>
    <link-entity name='entity'
      from='entityid'
      to='extensionofrecordid'
      link-type='inner'
      alias='entity'>
      <attribute name='logicalname' />
      <order attribute='logicalname' />
    </link-entity>
  </entity>
</fetch>

了解如何使用 FetchXml 查询数据

检测哪些表未启用已删除记录保留功能

要了解哪些表未启用已删除记录保留功能,请使用以下 FetchXml 查询,该查询与检测哪些表已启用中的查询相反。

<fetch>
  <entity name='entity'>
    <attribute name='logicalname' />
    <filter type='or'>
      <condition entityname='recyclebin'
        attribute='extensionofrecordid'
        operator='null' />
      <condition entityname='recyclebin'
        attribute='statecode'
        operator='ne'
        value='0' />
      <condition entityname='recyclebin'
        attribute='isreadyforrecyclebin'
        operator='ne'
        value='1' />
    </filter>
    <order attribute='logicalname' />
    <link-entity name='recyclebinconfig'
      from='extensionofrecordid'
      to='entityid'
      link-type='outer'
      alias='recyclebin' />
  </entity>
</fetch>

了解如何使用 FetchXml 查询数据

截至 2024 年 5 月(该功能启用之时)的查询结果位于当前不支持已删除记录保留的表中。

检索并设置已删除记录保留的自动清理时间段配置

RecycleBinConfig.CleanupIntervalInDays 列中设置一个值,该值确定已删除的记录在 Name 列值为 organization 时可被还原的时长。 RecycleBinConfig 表中每隔一行,其 CleanupIntervalInDays 列值均为 -1。 此值指示它使用为 organization 表设置的相同值。

若要为另一个表指定不同的值,请在 CleanupIntervalInDays 与表的逻辑名称匹配的情况下设置 Name 列的值。 此列接受高达 30 的值。 除非要使用不同于组织默认值的值,否则不要设置此值。

使用此静态 SetCleanupIntervalInDays 方法可设置特定表的 CleanupIntervalInDays 列值。

/// <summary>
/// Updates the CleanupIntervalInDays value for a specified table
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="entityId">The entityId of the table</param>
/// <param name="cleanupIntervalInDays">The new CleanupIntervalInDays value</param>
static void SetCleanupIntervalInDays(
    IOrganizationService service,
    Guid entityId,
    int cleanupIntervalInDays)
{

    QueryExpression query = new("recyclebinconfig")
    {
        ColumnSet = new ColumnSet("recyclebinconfigid"),
        Criteria = new FilterExpression(LogicalOperator.And)
        {
            Conditions = {
              {
                  new ConditionExpression(
                      attributeName: "extensionofrecordid",
                      conditionOperator: ConditionOperator.Equal,
                      value: entityId)
              }
          }
        }
    };

    EntityCollection records = service.RetrieveMultiple(query);

    if (records.Entities.Count.Equals(1))
    {
        Guid id = records.Entities[0].Id;

        Entity record = new(entityName: "recyclebinconfig", id: id)
        {
            Attributes = {
                { "cleanupintervalindays", cleanupIntervalInDays }
            }
        };

        service.Update(record);

    }
    else
    {
        throw new Exception($"Deleted record keeping configuration for table '{tableLogicalName}' not found.");
    }
}

使用 .NET 的软件开发工具包 (SDK)

为环境禁用已删除记录保留

注释

禁用环境中的已删除记录保留的首选方法是在 Power Platform 管理中心将其关闭。 在功能正式发布之前,此处介绍的方法可能会更改。

删除 回收站配置 表中 name 的值所在的 organization行。 此操作将删除 RecycleBinConfig 表中的所有记录,并禁用该环境的已删除记录保留功能。

重要

请勿尝试删除其他单个记录。 确保 Dataverse 负责管理此操作非常重要。

管理因自定义业务逻辑而删除的记录的还原

Dataverse 提供了一种机制,用于在删除行时管理相关记录的所需操作。 此配置数据是关系定义的一部分。 删除相关记录后,可以配置四种可能的行为:

删除行为 说明
全部级联 删除相关记录。
删除链接 将已删除记录的查阅列设置为 null。
无层叠 不对相关记录应用任何更改。 (仅限内部)
Restrict 防止删除记录以维护数据完整性。 除非没有与此关系相关的记录,否则无法删除该记录。

详细了解关系行为

Cascade AllRemove LinkRestrict 配置关系时,Dataverse 会管理这些行为,无需执行任何额外操作。

如果将关系配置为使用 “删除链接” 行为,但关系应删除相关记录,则可能需要应用某些自定义行为的自定义逻辑。 例如,你可能希望以不同的方式响应此行为,并根据定义的规则实现自己的 “Cascade some” 行为。 例如,可以删除在特定时间段内未更新的非活动记录或记录。 此逻辑通常是通过使用插件来实现的,但也可以通过将 Power Automate 与 Microsoft Dataverse 连接器配合使用来实现:添加、修改或删除行时触发

如果你有这种自定义业务逻辑,Dataverse 无法识别,并且无法自动“撤消”你的逻辑。 但是,你可以在 Restore 消息上注册另一个插件,以撤销你设置的任何自定义逻辑。 或者,您也可以使用 Power Automate 和 Microsoft Dataverse 连接器:执行操作时触发器

重要

Restore消息注册插件步骤时,请注意消息的上下文。 您要恢复的记录在 PreOperation 阶段不可用。 如果需要创建相关记录,请使用 PostOperation 阶段。 详细了解插件阶段

消息的 InputParametersOutputParametersRestoreCreate 消息类似,因此为 Create 消息编写并注册的插件只需少量修改即可重用于 Restore消息。

当前不支持已删除记录保留的表

2024 年 8 月,使用检测哪些表未启用中描述的查询生成了此列表

另请参阅

恢复已删除的Microsoft Dataverse表记录