Saturday, June 05, 2010

MSCRM 4.0: A Few Tips on Using CRM Configuration Data Utility

In case you are not aware, CRM Configuration Data Utility is a handy tool released by Microsoft sometime last year. What it does is to help you transfer CRM configuration data from one environment to another.

I recently happen to have the need to transfer some configuration data between two environments, so I spent a little time to poke around with the utility, and I am very pleased with the tool, but I quickly realized a few limitations with the toolkit that have been intentionally engineered by Microsoft team. Fortunately the utility comes with complete source code, so I was able to tweak it to meet my needs. Here are a couple of tips that might help you make best use of the tool.

  1. This utility is a really convenient tool if you want to transfer any configuration data stored in your custom entities. You can export data from one environment, and import to another one within a few mouse click. But here is the catch, it's engineered to only support the export and import of custom entities. But with the source code, you can easily change it to support any entities including system ones. What you need to do is to change the following code in ExportDataForm.cs file (RetrieveEntitiesComplete method)
    IEnumerable<EntityMetadata> entities = response.CrmMetadata
        .Cast<EntityMetadata>()
        .Where(entity => entity.IsIntersect.Value == false && entity.IsImportable.Value && entity.IsCustomEntity.Value)
        .OrderBy(entity => entity.DisplayName.UserLocLabel.Label)
        .ToList();
    
    
    to
    IEnumerable<EntityMetadata> entities = response.CrmMetadata
        .Cast<EntityMetadata>()
        .Where(entity => entity.IsIntersect.Value == false && entity.IsImportable.Value)
        .OrderBy(entity => entity.DisplayName.UserLocLabel.Label)
        .ToList();
    
    

  2. The utility is a smart tool, but it is a little bit too smart when it comes to the import. It will actually try to do duplicate check before importing the data. The duplicate check is based on the imported entity's primary attribute, which isn't correct all the time. Sometimes, we do have two different CRM records with the same value of the primary attribute. For instance, we have a self-referenced entity, which has a parent field to refer to the same entity itself. It's often the case that the primary attribute of two CRM records are the same, but they are linked to two different parents, they are essentially two different records in the business world. In order to have the utility to do straight import, you should comment out the following code in dynamicentityutility.cs file (GetByIdOrPrimaryAttribute method)
    // Locate the following code and comment out the entire block in dynamicentityutility.cs file
    // in order to stop the configuration data utility from performing duplicate check. 
    string primaryAttribute = MetadataUtility.RetrievePrimaryAttribute(metadataService, entityName);
    QueryExpression query = new QueryExpression(entityName)
    {
        ColumnSet = new ColumnSet(fields)
    };
    
    ConditionExpression primaryAttributeExpression = new ConditionExpression(primaryAttribute.ToLower(), ConditionOperator.Equal, primaryAttributeValue);
    query.Criteria.Conditions.Add(primaryAttributeExpression);
    
    RetrieveMultipleRequest request = new RetrieveMultipleRequest()
    {
        Query = query,
        ReturnDynamicEntities = true
    };
    
    RetrieveMultipleResponse response = (RetrieveMultipleResponse)_crmService.Execute(request);
    
    if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
        resultList.AddRange(response.BusinessEntityCollection.BusinessEntities.ConvertAll<DynamicEntity>(x=> (DynamicEntity)x));
    

The beauty about this tool is, you often configure your CRM workflows in one environment (for instance, your development environment), and those CRM workflows sometimes refer to particular CRM records as configuration data, so there is dependency between your workflow and those CRM records. When you export those workflows and import to a different environment (for instance, your production environment), you will have to re-create the same set of CRM records in the new environment in order to make the workflows work. But if you create the records manually, the records' internal ID (Guid) would be different, so you will have to reconfigure each workflow to point to the new created CRM records, otherwise, you would not be able to publish your workflows. But with the configuration data utility handy, you can simply transfer the configuration data, the IDs will remains the same as what it was in the original environment, so you don't have to reconfigure your workflows, it will save you tremendous effort when you try to promote workflows from one environment to another which have dependency on configuration data.

Hope this gives you some basic ideas about how to tweak the utility. In my opinion, it's a pretty well-engineered piece of software.

Looking for Sponsorship of Authoring a Dynamics CRM Development Book

After spending roughly 20 months of hard-working days with Microsoft Dynamics CRM 4.0, I thought I had learned tons of lessons that I can share with the community. An idea has been bugging me for a while recently is to author a Microsoft Dynamics CRM development book, I would appreciate if you could help me establish the connection if you happen to know anyone in a publishing house, or ever better you actually work as a publisher.

The idea about authoring a book is not about making me rich, actually I knew that writing a book most likely will not make you rich, but instead it could possibly make me poorer if the book itself sucks. My primary motivation is to share the knowledge and the experience that I have gained during the past nearly two years. I had some struggle in a very hard way at the beginning, so I believe that the lessons that I learned might be able to help new people who come to MSCRM development practice without much knowledge about the platform and its programming model.

What I am planning for the book is a type of development in action, and a recipe one. My intention is to keep bluffing out of the book, but focus on the real-world experience and the best practices of CRM Development. I knew there have been a few very good CRM development books on the market, but I do believe that I can still contribute in a different way. Since CRM5 is on the horizon, I am more interested in writing CRM5 instead of CRM4.

I believe my greatest strength is to make complex thing look simpler most of the time, occasionally I could possibly go the other way due to my technical mind, but it should be very rare case. Even though my MSCRM experience is not significantly long, I had roughly over a decade of IT experience by filling various roles, including Software Engineer, Solution Architect, Team Lead, and Project Manager. I believe I have very good vision about where Microsoft Dynamics CRM could possibly go, how to make best use of the platform, and further more, how to differentiate your technical solutions from your competitors in the market. I have an extreme passion about writing quality software code by leveraging the best practices of the industry. Sometime I may not be able to get it right the first time, but I never gave up learning and improving.

Of course, I am also open to any offer to co-author the book if that works out with the publishing house.

Please drop me a line of email if you have any connection or you are interested in the co-authoring, at danielwcai [at] gmail [dot] com.