This documentation is archived and is not being maintained.

How to Delete Asynchronous Operation Records

Forefront
banner art

[Applies to: Microsoft Dynamics CRM 4.0]

Find the latest SDK documentation: CRM 2015 SDK

The following code example demonstrates how to use the BulkDelete messages to delete asynchronous operation records that are in a completed state.

This sample code can be found in the following files in the SDK download:

SDK\Server\Howto\CS\BulkDelete\DeleteCompletedAsyncOperationRecords.cs
SDK\Server\Howto\VB\BulkDelete\DeleteCompletedAsyncOperationRecords.vb

For more information about the helper methods in the Microsoft.Crm.Sdk.Utility.CrmServiceUtility namespace, see Utility Sample Code.

Example

[C#]
using System;
using System.Xml;
using System.Web.Services.Protocols;
using Microsoft.Crm.Sdk.Utility;

namespace Microsoft.Crm.Sdk.HowTo.BulkDelete
{
    // Using the following Microsoft Dynamics CRM namespaces in the sample.
    using CrmSdk;

   /// <summary>
    /// This sample shows how to use BulkDelete messages to delete
    ///   async operation records that are in a completed state. 
    /// This will help to reduce the size of the AsyncOperationBase table.
   /// </summary>
   public class DeleteCompletedAsyncOperationRecords
   {
        static void Main(string[] args)
        {
            try
            {
                // TODO: Change the server URL and organization to match your 
                //  Microsoft Dynamics CRM Server and Microsoft Dynamics CRM Organization.
                DeleteCompletedAsyncOperationRecords.Run("http://localhost:5555", "CRM_Organization");
            }
            catch (SoapException ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.Detail.InnerText);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine(ex.Message);

                // Display the details of the inner exception.
                if (ex.InnerException != null)
                {
                    Console.WriteLine(ex.InnerException.Message);

                    SoapException se = ex.InnerException as SoapException;
                    if (se != null)
                        Console.WriteLine(se.Detail.InnerText);
                }
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit.");
                Console.ReadLine();
            }
        }

      public static bool Run(string crmServerUrl, string orgName)
      {
         
            // Set up the CRM Service.
            CrmService service = CrmServiceUtility.GetCrmService(crmServerUrl, orgName);
            // Cache credentials so each request does not have to be re-authenticated.
            service.PreAuthenticate = true;

            #region Setup Data Required for this Sample

            bool success = false;

            #endregion
         
            // Create a ConditionExpression for the condition of AsyncOperation state completed.
            ConditionExpression conditionStateCode = new ConditionExpression();
            conditionStateCode.AttributeName = "statecode";
            conditionStateCode.Operator = ConditionOperator.Equal;
            conditionStateCode.Values = new Object[1];
            conditionStateCode.Values[0] = (int)AsyncOperationState.Completed;

            // Create a ConditionExpression for the condition of AsyncOperation completedon.
            ConditionExpression conditionCompletedOn = new ConditionExpression();
            conditionCompletedOn.AttributeName = "completedon";
            conditionCompletedOn.Operator = ConditionOperator.OlderThanXMonths;
            conditionCompletedOn.Values = new Object[1];
            conditionCompletedOn.Values[0] = 1;
            
            // Create a ConditionExpression for the condition of AsyncOperation operationtype.
            ConditionExpression conditionOperationType = new ConditionExpression();
            conditionOperationType.AttributeName = "operationtype";
            conditionOperationType.Operator = ConditionOperator.NotEqual;
            conditionOperationType.Values = new Object[1];
            conditionOperationType.Values[0] = (int)AsyncOperationType.Workflow;

            // Create the FilterExpression.
            FilterExpression filterPrincipal = new FilterExpression();
            filterPrincipal.FilterOperator = LogicalOperator.And;
            filterPrincipal.Conditions = new ConditionExpression[] { 
                conditionStateCode, conditionCompletedOn, conditionOperationType };

            // Create a column set that holds the name of the column to be retrieved.
            ColumnSet colsAsycOperation = new ColumnSet();
            colsAsycOperation.Attributes = new string[] { "asyncoperationid" };

            // Create the QueryExpression.
            QueryExpression expression = new QueryExpression();

            // Set the QueryExpression properties.
            expression.EntityName = EntityName.asyncoperation.ToString();
            expression.ColumnSet = colsAsycOperation;
            expression.Criteria = filterPrincipal;

            // Create a list of empty recipients.
            Guid[] emptyRecipients = new Guid[0];

            // Create BulkDelete request.
            BulkDeleteRequest request = new BulkDeleteRequest();

            // Set the request properties.
            request.JobName = "Bulk delete completed asyncoperations to free up space";
            request.QuerySet = new QueryBase[] { expression };

            // Set e-mail activity properties.
            request.ToRecipients = emptyRecipients;
            request.CCRecipients = emptyRecipients;
            request.SendEmailNotification = false;

            // Set the required recurrence pattern.
            request.RecurrencePattern = string.Empty;
            
            // Set the start time for the bulk delete.
            request.StartDateTime = CrmDateTime.Now;

            // Submit the bulk delete job.
            BulkDeleteResponse response = (BulkDeleteResponse)service.Execute(request);

              #region check success
         
         // Query for bulk delete operation and check for status.
         QueryByAttribute bulkQuery = new QueryByAttribute();
         // Be aware that using AllColumns may adversely affect
         // performance and cause unwanted cascading in subsequent 
         // updates. A best practice is to retrieve the least amount of 
         // data required.
         bulkQuery.ColumnSet = new AllColumns();
         bulkQuery.EntityName = EntityName.bulkdeleteoperation.ToString();

         // NOTE: When the bulk delete operation was submitted, the GUID that was returned 
         // was the asyncoperationid, not the bulkdeleteoperationid.
         bulkQuery.Attributes = new string[] { "asyncoperationid" };
         bulkQuery.Values = new object[1];
         bulkQuery.Values[0] = response.JobId;

         // With only the asyncoperationid at this point, a RetrieveMultiple is required to get the
         // bulk delete operation created previously.
         BusinessEntityCollection entityCollection = service.RetrieveMultiple(bulkQuery);
         bulkdeleteoperation createdBulkDeleteOperation = null;

         // Monitor the async operation via polling until it is complete or the max polling time expires.
         const int ARBITRARY_MAX_POLLING_TIME = 60;
         int secondsTicker = ARBITRARY_MAX_POLLING_TIME;
         while (secondsTicker > 0)
         {
            // Make sure the async operation was retrieved.
            if (entityCollection.BusinessEntities.Length > 0)
            {
               // Grab the one bulk operation that has been created.
               createdBulkDeleteOperation = (bulkdeleteoperation)entityCollection.BusinessEntities[0];

               // Check the operation's state.
               if (createdBulkDeleteOperation.statecode.Value != BulkDeleteOperationState.Completed)
               {
                  // The operation has not yet completed.  Wait a second for the status to change.
                  System.Threading.Thread.Sleep(1000);
                  secondsTicker--;

                  // Retrieve a fresh version of the bulk delete operation.
                  entityCollection = service.RetrieveMultiple(bulkQuery);
               }
               else
               {
                  // Stop polling because the operation's state is now complete.
                  secondsTicker = 0;
               }
            }
            else
            {
               // Wait a second for async operation to activate.
               System.Threading.Thread.Sleep(1000);
               secondsTicker--;

               // Retrieve the entity again.
               entityCollection = service.RetrieveMultiple(bulkQuery);
            }
         }

         // Validate that the operation was completed.
         if (createdBulkDeleteOperation.statecode.Value != BulkDeleteOperationState.Completed)
         {
            // This will happen if it took longer than the polling time allowed 
            // for this operation to compete.
            success = false;
         }
         else
         {
                Console.WriteLine("Records successfully deleted: " + createdBulkDeleteOperation.successcount.Value.ToString());
                Console.WriteLine("Records failed: " + createdBulkDeleteOperation.failurecount.Value.ToString());
                if (createdBulkDeleteOperation.statuscode.name != "Succeeded")
                {
                    Console.WriteLine("The Bulk delete operation is still running and might take more time to complete.");
                    Console.WriteLine("Please check status of this operation in CRM system Settings > Data Management.");
                    success = false;
                }
                else
                {
                    Console.WriteLine("The Bulk delete operation completed successfully.");
                    success = true;
                }
         }

         #endregion

         #region Remove Data Required for this Sample

         // NOTE: The bulkdeleteoperation entity cannot be removed from the database.

         #endregion
         

         return success;
      }
        
   }
}
[Visual Basic .NET]
Imports Microsoft.VisualBasic
Imports System
Imports System.Xml
Imports System.Web.Services.Protocols
Imports Microsoft.Crm.Sdk.Utility

Imports CrmSdk
Namespace Microsoft.Crm.Sdk.HowTo.BulkDelete
    ' Using the following Microsoft Dynamics CRM namespaces in the sample.

    ''' <summary>
    ''' This sample shows how to use BulkDelete messages to delete
    '''   async operation records that are in a completed state. 
    ''' This will help to reduce the size of the AsyncOperationBase table.
    ''' </summary>
    Public Class DeleteCompletedAsyncOperationRecords
        Shared Sub Main(ByVal args() As String)
            Try
                ' TODO: Change the server URL and organization to match your 
                '  Microsoft Dynamics CRM Server and Microsoft Dynamics CRM Organization.
                DeleteCompletedAsyncOperationRecords.Run("http://localhost:5555", "CRM_Organization")
            Catch ex As SoapException
                Console.WriteLine("The application terminated with an error.")
                Console.WriteLine(ex.Message)
                Console.WriteLine(ex.Detail.InnerText)
            Catch ex As System.Exception
                Console.WriteLine("The application terminated with an error.")
                Console.WriteLine(ex.Message)

                ' Display the details of the inner exception.
                If ex.InnerException IsNot Nothing Then
                    Console.WriteLine(ex.InnerException.Message)

                    Dim se As SoapException = TryCast(ex.InnerException, SoapException)
                    If se IsNot Nothing Then
                        Console.WriteLine(se.Detail.InnerText)
                    End If
                End If
            Finally
                Console.WriteLine("Press <Enter> to exit.")
                Console.ReadLine()
            End Try
        End Sub

        Public Shared Function Run(ByVal crmServerUrl As String, ByVal orgName As String) As Boolean

            ' Set up the CRM Service.
            Dim service As CrmService = CrmServiceUtility.GetCrmService(crmServerUrl, orgName)
            ' Cache credentials so each request does not have to be re-authenticated.
            service.PreAuthenticate = True

            '         #Region "Setup Data Required for this Sample"

            Dim success As Boolean = False

            '         #End Region

            ' Create a ConditionExpression for the condition of AsyncOperation state completed.
            Dim conditionStateCode As New ConditionExpression()
            conditionStateCode.AttributeName = "statecode"
            conditionStateCode.Operator = ConditionOperator.Equal
            conditionStateCode.Values = New Object(0) {}
            conditionStateCode.Values(0) = CInt(Fix(AsyncOperationState.Completed))

            ' Create a ConditionExpression for the condition of AsyncOperation completedon.
            Dim conditionCompletedOn As New ConditionExpression()
            conditionCompletedOn.AttributeName = "completedon"
            conditionCompletedOn.Operator = ConditionOperator.OlderThanXMonths
            conditionCompletedOn.Values = New Object(0) {}
            conditionCompletedOn.Values(0) = 1

            ' Create a ConditionExpression for the condition of AsyncOperation operationtype.
            Dim conditionOperationType As New ConditionExpression()
            conditionOperationType.AttributeName = "operationtype"
            conditionOperationType.Operator = ConditionOperator.NotEqual
            conditionOperationType.Values = New Object(0) {}
            conditionOperationType.Values(0) = CInt(Fix(AsyncOperationType.Workflow))

            ' Create the FilterExpression.
            Dim filterPrincipal As New FilterExpression()
            filterPrincipal.FilterOperator = LogicalOperator.And
            filterPrincipal.Conditions = New ConditionExpression() { _
            conditionStateCode, conditionCompletedOn, conditionOperationType}

            ' Create a column set that holds the name of the column to be retrieved.
            Dim colsAsycOperation As New ColumnSet()
            colsAsycOperation.Attributes = New String() {"asyncoperationid"}

            ' Create the QueryExpression.
            Dim expression As New QueryExpression()

            ' Set the QueryExpression properties.
            expression.EntityName = EntityName.asyncoperation.ToString()
            expression.ColumnSet = colsAsycOperation
            expression.Criteria = filterPrincipal

            ' Create a list of empty recipients.
            Dim emptyRecipients(-1) As Guid

            ' Create BulkDelete request.
            Dim request As New BulkDeleteRequest()

            ' Set the request properties.
            request.JobName = "Bulk delete completed asyncoperations to free up space"
            request.QuerySet = New QueryBase() {expression}

            ' Set e-mail activity properties.
            request.ToRecipients = emptyRecipients
            request.CCRecipients = emptyRecipients
            request.SendEmailNotification = False

            ' Set the required recurrence pattern.
            request.RecurrencePattern = String.Empty

            ' Set the start time for the bulk delete.
            request.StartDateTime = CrmDateTime.Now

            ' Submit the bulk delete job.
            Dim response As BulkDeleteResponse = CType(service.Execute(request), BulkDeleteResponse)

            '            #Region "check success"

            ' Query for bulk delete operation and check for status.
            Dim bulkQuery As New QueryByAttribute()
         ' Be aware that using AllColumns may adversely affect 
         ' performance and cause unwanted cascading in subsequent 
         ' updates.  A best practice is to retrieve the least amount of 
         ' data required.
            bulkQuery.ColumnSet = New AllColumns()
            bulkQuery.EntityName = EntityName.bulkdeleteoperation.ToString()

            ' NOTE: When the bulk delete operation was submitted, the GUID that was returned 
            ' was the asyncoperationid, not the bulkdeleteoperationid.
            bulkQuery.Attributes = New String() {"asyncoperationid"}
            bulkQuery.Values = New Object(0) {}
            bulkQuery.Values(0) = response.JobId

            ' With only the asyncoperationid at this point, a RetrieveMultiple is required to get the
            ' bulk delete operation created previously.
            Dim entityCollection As BusinessEntityCollection = service.RetrieveMultiple(bulkQuery)
            Dim createdBulkDeleteOperation As bulkdeleteoperation = Nothing

            ' Monitor the async operation via polling until it is complete or the max polling time expires.
            Const ARBITRARY_MAX_POLLING_TIME As Integer = 60
            Dim secondsTicker As Integer = ARBITRARY_MAX_POLLING_TIME
            Do While secondsTicker > 0
                ' Make sure the async operation was retrieved.
                If entityCollection.BusinessEntities.Length > 0 Then
                    ' Grab the one bulk operation that has been created.
                    createdBulkDeleteOperation = CType(entityCollection.BusinessEntities(0), bulkdeleteoperation)

                    ' Check the operation's state.
                    If createdBulkDeleteOperation.statecode.Value <> BulkDeleteOperationState.Completed Then
                        ' The operation has not yet completed.  Wait a second for the status to change.
                        System.Threading.Thread.Sleep(1000)
                        secondsTicker -= 1

                        ' Retrieve a fresh version of the bulk delete operation.
                        entityCollection = service.RetrieveMultiple(bulkQuery)
                    Else
                        ' Stop polling because the operation's state is now complete.
                        secondsTicker = 0
                    End If
                Else
                    ' Wait a second for async operation to activate.
                    System.Threading.Thread.Sleep(1000)
                    secondsTicker -= 1

                    ' Retrieve the entity again.
                    entityCollection = service.RetrieveMultiple(bulkQuery)
                End If
            Loop

            ' Validate that the operation was completed.
            If createdBulkDeleteOperation.statecode.Value <> BulkDeleteOperationState.Completed Then
                ' This will happen if it took longer than the polling time allowed 
                ' for this operation to compete.
                success = False
            Else
                Console.WriteLine("Records successfully deleted: " & _
                                  createdBulkDeleteOperation.successcount.Value.ToString())
                Console.WriteLine("Records failed: " & createdBulkDeleteOperation.failurecount.Value.ToString())
                If createdBulkDeleteOperation.statuscode.name <> "Succeeded" Then
                    Console.WriteLine("The Bulk delete operation is still running and might take more time to complete.")
                    Console.WriteLine("Please check status of this operation in CRM system Settings > Data Management.")
                    success = False
                Else
                    Console.WriteLine("The Bulk delete operation completed successfully.")
                    success = True
                End If
            End If

            '         #End Region

            '         #Region "Remove Data Required for this Sample"

            ' NOTE: The bulkdeleteoperation entity cannot be removed from the database.

            '         #End Region


            Return success
        End Function

    End Class
End Namespace

See Also

Reference


© 2010 Microsoft Corporation. All rights reserved.


Show: