Search code examples
c#dynamics-crm-2011dynamics-crm

Merge Contacts in Dynamics CRM using C#


So I am writing a console application that merges duplicated contacts in a CRM deployment.

There are two parts to this code. The part that gets the GUID's of the duplicate records and the part that does the actual merging. My problem lies in the former.

I use the phone numbers of the customers to check for uniqueness as you can see in the code and there is a txt file that contains each number in a new line.

I need to fill a list of contacts from this text file and pass it along to the merging method.

I can define a hard-coded string and it works that way but

The part that actually does the merging works but the part that fills all of these duplicates in to a List and and passes it along doesn't. I tried filling it as if it was a list of strings but apperantly this is not how it works with contacts.

The code is included below.

using System;
using System.ServiceModel;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Zeno.Business;
using Zeno.Configuration;
using Zeno.CRMEntityModel;
using System.Collections.Generic;
using System.IO;

namespace MergeTool
{

    public static class MergeContact
    {

        public static ContactBL bl = new ContactBL();



        /// <param name="serverConfig">Contains server connection information.</param>
        /// <param name="promptForDelete">When True, the user will be prompted to delete
        /// all created entities.</param>
        public static void Merge()
        {
            List<Contact> contactList = getAccountGuids();

            for (int i = 0; i < contactList.Count; i++)
            {
                Contact contact = contactList[0];
                Contact _subContact = contactList[1];
                EntityReference target = new EntityReference();

                target.Id = contact.ContactId.Value;
                target.LogicalName = Contact.EntityLogicalName;

                MergeRequest merge = new MergeRequest();
                merge.SubordinateId = _subContact.ContactId.Value;
                merge.Target = target;
                merge.PerformParentingChecks = false;

                Contact updateContent = new Contact();
                updateContent.zeno_nebimcustomernumber = _subContact.zeno_nebimcustomernumber;
                //updateContent....
                if (string.IsNullOrEmpty(contact.FirstName))
                {
                    updateContent.FirstName = _subContact.FirstName;
                }
                //further if conditions clipped for brevity

                merge.UpdateContent = updateContent;

                MergeResponse merged = (MergeResponse)bl.Execute(merge);

            }
        }

        public static List<Contact> getAccountGuids()
        {
            //TO DO
            // Get all duplicate contact mobile phone numbers

            string mobilePhone = "+90(505)220 72 29";

            return bl.RetrieveContactListByMobilePhone(mobilePhone);
        }
    }
}

As per request I have included the contents of ContactsBL below.

using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Zeno.CRMEntityModel;
using Zeno.Repository;

namespace Zeno.Business
{
    public class ContactBL:BLBase
    {

        private ContactRepository contactRepository;

        public ContactBL()
            : base()
        {
        }

        public ContactBL(IOrganizationService service)
            : base(service)
        {
        }

        public Guid CheckPhoneNumber(string phoneNumber)
        {
            this.contactRepository = new ContactRepository(this.Connection);

            return contactRepository.CheckPhoneNumber(phoneNumber);
        }




        public List<Contact> RetrieveContactListByMobilePhone(string phoneNumber)
        {
            this.contactRepository = new ContactRepository(this.Connection);

            return contactRepository.RetrieveContactListByMobilePhone(phoneNumber);
        }

    }
}

Solution

  • Looks like you forgot the i.

    You don't want to use indexes 0 and 1 in your main loop, because that would merge the first two entities over and over again. You should use your iterator variable i instead.

    Instead of initializing your contacts with absolute indexes:

            Contact contact = contactList[0];
            Contact _subContact = contactList[1];
    

    You should use the iterator variable.

            Contact contact = contactList[i];
            Contact _subContact = contactList[i+1];
    

    Update : Possible IndexOutOfBoundsException

    Beware of the possible IndexOutOfBoundsException which may be thrown because of the contactList[i+1] reference. You should avoid this by comparing against contactList.Count - 1 instead of contaclist.Count. :

    // BAD! : contactList[i+1] would throw IndexOutOfBoundsException on the last cycle.
    for(int i=0; i < contactList.Count; i++) 
    
    // GOOD : contactList[i+1] would point to the last item in the last cycle so it should be okay.
    for(int i=0; i < contactList.Count - 1; i++)