Dynamics 365 – Restore Deleted Records

If you want to restore any records that have been deleted for any reason (a clumsy employee or a misunderstanding 😉), it’s possible to do so with C#. Let me also note that this feature is still in the preview stage while writing this post.

Retrieving Deleted Records

Before restoring a record, we need to find it first. Deleted records are stored in a special “bin” datasource. You can retrieve them using FetchXML or QueryExpression

FetchXML Example

This example retrieves up to three deleted contact records:

static EntityCollection GetDeletedContactRecordsFetchXml(IOrganizationService service) {
   string queryString = @"<fetch datasource='bin'>
                     <entity name='contact'>
                        <attribute name='contactid' />
                        <attribute name='fullname' />
                     </entity>
                     </fetch>";
   
   FetchExpression query = new(queryString);
   return service.RetrieveMultiple(query);
}

QueryExpression Example

Same retrieval process but using QueryExpression:

static EntityCollection GetDeletedContactRecordsQueryExpression(IOrganizationService service) {
   QueryExpression query = new("contact") {
         ColumnSet = new ColumnSet("fullname", "contactid"),
         DataSource = "bin",
         TopCount = 50
   };
   return service.RetrieveMultiple(query);
}

Restoring a Deleted Record

Once we have the deleted record, we can restore it. Restoring works by creating a new instance of the record with its original values and passing it to the RestoreRequest<T>.

Example: Restoring a Contact Record

static Guid RestoreContactRecord(IOrganizationService service, Guid contactId, string originalFullName) {
    Contact contactToRestore = new() {
        Id = contactId,
        FullName = originalFullName + " (Restored)"
    };

    RestoreRequest<Contact> request = new() {
        Target = contactToRestore
    };

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

⚠️Note: At the moment, you can only restore records using their primary key (GUID). Alternate keys are not supported.

Checking if Recycle Bin is Enabled for a Table

Not all tables support the recycle bin. To check which tables have it enabled, query the RecycleBinConfig table:

<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>

Disabling Recycle Bin for a Table

Admins can disable the recycle bin for a specific table by updating the RecycleBinConfig record.

static void DisableRecycleBinForTable(IOrganizationService service, Guid tableEntityId) {
    QueryExpression query = new("recyclebinconfig") {
        ColumnSet = new ColumnSet("recyclebinconfigid")
    };

    LinkEntity entityLink = query.AddLink("entity", "extensionofrecordid", "entityid");
    entityLink.LinkCriteria.AddCondition("extensionofrecordid", ConditionOperator.Equal, tableEntityId);

    EntityCollection recyclebinconfigs = service.RetrieveMultiple(query);

    if (recyclebinconfigs.Entities.Count.Equals(1)) {
        var id = recyclebinconfigs.Entities[0].GetAttributeValue<Guid>("recyclebinconfigid");

        Entity recyclebinconfig = new("recyclebinconfig", id) {
            Attributes = {
                { "statecode", new OptionSetValue(1) },
                { "statuscode", new OptionSetValue(2) }
            }
        };
        service.Update(recyclebinconfig);
    } else {
        throw new Exception($"Recycle bin configuration for table '{tableEntityId}' not found.");
    }
}

Conclusion

The recycle bin feature in Dynamics 365 is a great safety net for accidental deletions. Ensure your tables support the recycle bin, and disable it where necessary. Happy coding!

Leave a comment