Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • Importing Records and the CRMDeletionService

    Posted on March 27th, 2007 mitch Print Print No comments

    As you may know, each record within the CRM system has a unique identifier that identifies it within the system. This identifier is know as a GUID, or a Globally Unique ID.

    When you programmatically import records into CRM, you can either supply the GUID yourself, as a item within the import dataset, or you may allow CRM to generate the GUID.

    I was using a modified version of the Bulk Import Utility that I mentioned a while back and for this particular implementation, it made the import much more efficient if I supplied the GUID during the import process. 

    NOTE: In such a case all you do is assign the value of the GUID to the Entity's ID column, such as:

    Lookup keyTestValue = new Lookup();
    keyTestValue.Value = new Guid(myGUID);
    keyTestValue.type = EntityName.contact.ToString();

    This worked great for a while. I would test a section of the import process, delete the imported records, and reimport them later.

    Then I started running to very strange errors:

    Server was unable to process request.

    Not exactly though provoking or even any help at all in leading me to the root cause of the problem.

    The Problem

    It turns out, that even though I had deleted my test import records from CRM, they were still in the database.

    This is a common practice, and in case you didn't know, the CRM Client does not physically delete CRM records – it merely marks them for Deletion.  The CRMDeletionService is the process that runs periodically and makes everything in the CRM world right again.

    Except my CRM world wasn't right at all.  I couldn't continue my development efforts since I couldn't reliably test my import process, I had no idea why it was suddenly broken, and I had people at the customer site waiting on me to finish.

    I finally traced the issue to the fact that I was importing the GUID IDs along with the other Entity data.  I am making an educated guess that CRM was getting upset that it was finding those IDs existing within the database during the Create process and the import for that record was failing.

    I didn't want to result to manually deleting records from the CRM Base tables because that's against the rules, and I had no idea what magic was required to manually fire off the CRMDeletionService to have it do it's job.

    So I did what I usually do in cases like this: I sent a panicked email to a couple of my fellow CRM MVPs for thoughts and ideas.

    The Solution

    Michael Höhne came to my rescue with a bit of CRM knowledge that I am sharing now.  It turns out that you can instruct the CRMDeletionService to run manually, using the following instructions:

    1) Open a command prompt.

    2) Change your directory to: [CRM installation directory]\server\bin

    3) Run crmdeletionservice –runonce

    That will run the CRMDeletionService which will remove the deleted records from the database.

    CRM Deleted Records Backgrounder

    As mentioned above, the CRM client is not actually the process that deletes CRM records, it is the CRMDeletionService that does the actual work.  This is probably due to the fact that Delete operations are fairly intensive processes and due to the Entity Relationships you find within CRM, it can be extremely complex and time consuming.

    Rather than burden the user with this effort, the CRM Client merely updates the individual records and changes the DeletionStateCode to a value of 2.  The CRMDeletionService wakes up on a periodic basis ( unknown and not documented, BTW ), and deletes any record with the DeletionStateCode of 2.

    This makes for a fairly efficient system and an overall better user experience.

    Should you be accessing CRM data via the SQL Filtered Views, the DeletionStateCode value is taken into account and records marked for deletion are not returned.

    Likewise, the CRM Clients both mirror this functionality and totally ignore records marked for deletion.

    Future Development Efforts

    One of the first CRM add-ons I ever wrote was a utility that performed a bulk delete of CRM data, using the CRM WebService APIs.  Unfortunately, it doesn't always function as expected and I haven't had the time to invest into tracking down the issues relating to the failure of the CrmService.Delete call.  I think most of these issues are related to relationships and cascading issues.

    I will also be adding an option to physically delete the records marked for deletion by running the CRMDeletionService -runonce.  That will be a valuable edition.

    It may also be possible to create an Undelete utility for CRM but I have no idea if you can "legally" set the DeletionStateCode back to 0 through the CRM Web Services.  There will also be tons of issues related to relationships and cascading behaviors that need to be taken into account.  All of which means it may not possible, or practical to create such a utility.

    Development, Dynamics CRM, Installation
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    3,072 views

    Leave a reply