Merging Entities in Dynamics CRM using Webservices and MergeRequest

If you have lots of duplicated accounts in you system that has lots of records like Orders or Invoices under them, you can use MergeRequest to merge those accounts.

The good thing about merge is that it will handle all relationships for you and you don’t have to worry about related order or invoices ,etc. you also define what fields you want to copy from duplicated record to main record.

Here is a sample code for merging all duplicated accounts in CRM:

I retrieve all accounts in CRM where their account number contains “-0” and then based on that criteria retrieved the duplicated.

If you have more than 5000 records , the Retrieve Multiple will only return first 5000 records so it’s better to use “ConditionOperator” to restrict the number of accounts to be retrieved in your QueryExpression. I find it really useful and fast. Use  “ConditionOperator.Like“…

private void btnMerge_Click(object sender, EventArgs e)
        {
            //connecting to the service and getting the credentials from app.confi
            ClientCredentials Credentials = new ClientCredentials();
            ClientCredentials oClientCredential = new ClientCredentials();
            oClientCredential.UserName.UserName = System.Configuration.ConfigurationManager.AppSettings["userName"];
            oClientCredential.UserName.Password = System.Configuration.ConfigurationManager.AppSettings["password"];

            Uri OrganizationUri = new Uri(System.Configuration.ConfigurationManager.AppSettings["CRMURI"]);
            Uri HomeRealmUri = null;

            using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, oClientCredential, null))
            {
                try
                {
                    IOrganizationService service = (IOrganizationService)serviceProxy;

                    QueryExpression query = new QueryExpression();

                    query.EntityName = "account";

                    query.ColumnSet = new ColumnSet() { AllColumns = true };

                    query.Criteria = new FilterExpression();

                    query.Criteria.FilterOperator = LogicalOperator.And;

                    query.Criteria.Conditions.Add

                    (
                     new ConditionExpression("statuscode", ConditionOperator.Equal, 1)//all the active accounts
                    );

                    query.Criteria.Conditions.Add(new ConditionExpression("accountnumber", ConditionOperator.Like, "%-0%"));

                    EntityCollection entities = service.RetrieveMultiple(query);

                    //loop through the list of retrieved entities and find the duplicate that match the criteria 

                    foreach (var item in entities.Entities)
                    {
                        string accountNumber = item.GetAttributeValue<string>("accountnumber").ToString();
                        string mainAccountNumber = item.GetAttributeValue<string>("dtm_mainaccountnumber").ToString();
                        string accountName = item.GetAttributeValue<string>("name").ToString();

                        if (accountNumber.Contains("-0"))
                        {
                            int start = accountNumber.IndexOf('-');
                            string strAdressCode = accountNumber.Substring(start + 1, accountNumber.Length - start - 1);
                            int number;
                            if (Int32.TryParse(strAdressCode, out number))
                            {
                                EntityReference target = new EntityReference();
                                target.Id = item.Id;
                                target.LogicalName = "account";

                                string newAccountNumber = accountNumber.Substring(0, start + 1) + number;

                                QueryExpression innerQuery = new QueryExpression();
                                innerQuery.EntityName = "account";
                                innerQuery.ColumnSet = new ColumnSet() { AllColumns = true };
                                innerQuery.Criteria = new FilterExpression();
                                innerQuery.Criteria.FilterOperator = LogicalOperator.And;
                                innerQuery.Criteria.Conditions.Add(new ConditionExpression("statuscode", ConditionOperator.Equal, 1));
                                innerQuery.Criteria.Conditions.Add(new ConditionExpression("dtm_mainaccountnumber", ConditionOperator.Equal, mainAccountNumber));
                                //innerQuery.Criteria.Conditions.Add(new ConditionExpression("name", ConditionOperator.Equal, accountName));
                                innerQuery.Criteria.Conditions.Add(new ConditionExpression("accountnumber", ConditionOperator.Equal, newAccountNumber));

                                EntityCollection innerEntities = service.RetrieveMultiple(innerQuery);

                                if (innerEntities.Entities.Count >= 1)
                                {

                                    // Create the request for Merge
                                    MergeRequest merge = new MergeRequest();
                                    merge.SubordinateId = innerEntities.Entities[0].Id;
                                    merge.Target = target;
                                    merge.PerformParentingChecks = false;
                                    
                                    // Create another account to hold new data to merge into the entity.
                                    // If you use the subordinate account object, its data will be merged.
                                    Entity updateContent = new Entity("account");
                                    updateContent["dtm_ismerged"] = "merged";

                                    // Set the content you want updated on the merged account
                                    merge.UpdateContent = updateContent;

                                    service.Execute(merge);
                                }
                            }
                            continue;
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.ToString());
                    string fileloc = "C:\\myLog.txt";

                    if (File.Exists(fileloc))
                    {
                        using (StreamWriter sw = new StreamWriter(fileloc))
                        {
                            sw.Write(ex.ToString());
                        }
                    }

                }
            }
        }

Advertisements

One thought on “Merging Entities in Dynamics CRM using Webservices and MergeRequest

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s