Hi All
I am using LINQ query to perform lead merge. It is working fine untill I have used lookup fields. Schema name for my lookup field is "countryregionid". I can see other people have faced the similar issue and try to use the fix advised but none work for me. It will be appreciated if someone point me to the right direction. Below is the code I am using. Please let me know if you need any further information. Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
namespace LeadsDataDeduplicationForm.CRM
{
public class CrmLead
{
/// <summary>
/// Merges the leads.
/// </summary>
/// <param name="targetPrimaryLead">The target primary lead.</param>
/// <param name="secondaryLead">The source lead.</param>
/// <param name="crmConnection">The CRM connection.</param>
/// <returns></returns>
public static void MergeLeads(ref Lead targetPrimaryLead, Lead secondaryLead, IOrganizationService crmConnection)
{
var uc = new Lead();
//Setting up the value of Contact Methods
uc.DoNotBulkEMail = targetPrimaryLead.DoNotBulkEMail | secondaryLead.DoNotBulkEMail;
uc.DoNotEMail = targetPrimaryLead.DoNotEMail | secondaryLead.DoNotEMail;
uc.DoNotFax = targetPrimaryLead.DoNotFax | secondaryLead.DoNotFax;
uc.DoNotPhone = targetPrimaryLead.DoNotPhone | secondaryLead.DoNotPhone;
uc.DoNotPostalMail = targetPrimaryLead.DoNotPostalMail | secondaryLead.DoNotPostalMail;
uc.DoNotSendMM = targetPrimaryLead.DoNotSendMM | secondaryLead.DoNotSendMM;
uc.score = secondaryLead.score;
uc.Salutation = secondaryLead.Salutation;
uc.countryregionid = secondaryLead.countryregionid;
var mergeRequest = new MergeRequest
{
Target = targetPrimaryLead.ToEntityReference(),
SubordinateId = secondaryLead.Id,
PerformParentingChecks = false,
UpdateContent = uc
};
crmConnection.Execute(mergeRequest);
targetPrimaryLead.DoNotBulkEMail = uc.DoNotBulkEMail;
targetPrimaryLead.DoNotEMail = uc.DoNotEMail;
targetPrimaryLead.DoNotFax = uc.DoNotFax;
targetPrimaryLead.DoNotPhone = uc.DoNotPhone;
targetPrimaryLead.DoNotPostalMail = uc.DoNotPostalMail;
targetPrimaryLead.DoNotSendMM = uc.DoNotSendMM;
targetPrimaryLead.score = uc.score;
targetPrimaryLead.Salutation = uc.Salutation;
targetPrimaryLead.countryregionid = uc.countryregionid;
}
/// <summary>
/// Gets all duplicate leads.
/// </summary>
/// <returns></returns>
public static void ProcessDuplicateLeads(IOrganizationService crmConnection)
{
// retrieve leads with the same name and email address
using (var orgContext = new OrganizationServiceContext(crmConnection))
{
var queryResult = orgContext.CreateQuery<Lead>().Where(x => x.StateCode == LeadState.Open
&& x.LeadSourceCode.Value == 100000000
).Select(x => new Lead
{
Id = x.Id, EMailAddress1 = x.EMailAddress1,EstimatedCloseDate = x.CreatedOn,FirstName = x.FirstName,LastName = x.LastName,gmass_data_sort = x.gmass_data_sort,
OriginalSource = x.OriginalSource, DoNotBulkEMail = x.DoNotBulkEMail, DoNotEMail = x.DoNotEMail, DoNotFax = x.DoNotFax, DoNotPhone = x.DoNotPhone,
DoNotPostalMail = x.DoNotPostalMail, DoNotSendMM = x.DoNotSendMM, score = x.score, Salutation = x.Salutation, Suffix = x.Suffix, gender = x.gender,
birth_date = x.birth_date, nationality = x.nationality, MobilePhone = x.MobilePhone, EMailAddress2 = x.EMailAddress2, Telephone2 = x.Telephone2,
Address1_Line1 = x.Address1_Line1, Address1_Line2 = x.Address1_Line2, Address1_City = x.Address1_City, Address1_StateOrProvince = x.Address1_StateOrProvince,
Address1_PostalCode = x.Address1_PostalCode,
Address1_MetroArea = x.Address1_MetroArea,
countryregionid = x.countryregionid,
}).ToList();
//order the lead list by the new custom temporary sort field. the highest number lead will be the target and the secondary one will roll-up any updates to the primary one.
var filterredResult = (from lead in queryResult
orderby lead.CreatedOn //descending
group lead by new {Email = lead.EMailAddress1, Name = lead.FullName} into grp
where grp.Count() > 1
select grp).ToList();
Console.WriteLine("Found {0} duplicate leads.", filterredResult.Count);
// skip the process as there is no duplicate found
if (filterredResult.Count <= 0) return;
Console.WriteLine("Begin the duplicate merging requests..");
// loop through the groupped leads
for (var i = 0; i < filterredResult.Count; i++)
{
var res = filterredResult[i];
// drill down to the items in the groupped leads
var primaryLead = res.First();
foreach (var element in res.Where(x => x.Id != primaryLead.Id))
{
// check the source lead whether they are part of Marketing List or not, if yes. Append the primary one to the Marketing List
var marketingListIds = SearchLeadMembership(element.Id, crmConnection);
// only do the marketing list assignment when there is any marketing listid found
if (marketingListIds.Any())
{
// loop through the marketing list id that found
foreach (var marketingListId in marketingListIds)
{
// add the primary to the marketing list
Console.WriteLine("Adding the Primary Lead to the marketing list where the secondary Lead belongs to");
CrmMarketingList.AddToMarketingList(primaryLead.Id, marketingListId, crmConnection);
// remove the secondary from the marketing list
CrmMarketingList.RemoveFromMarketingList(element.Id, marketingListId, crmConnection);
}
}
// execute the merge request
Console.WriteLine("Merging secondary lead {0} to primary lead {1}", element.Id, primaryLead.Id);
MergeLeads(ref primaryLead, element, crmConnection);
}
if (i % 200 == 0)
{
// sleep for 10 second to clear the resources
Thread.Sleep(10000);
}
}
}
}
/// <summary>
/// Gets the marketing list ids that a lead belongs to.
/// </summary>
/// <param name="leadId">The lead identifier.</param>
/// <param name="crmConnection">The CRM connection.</param>
/// <returns></returns>
public static List<Guid> SearchLeadMembership(Guid leadId, IOrganizationService crmConnection)
{
var listIds = new List<Guid>();
using (var orgContext = new OrganizationServiceContext(crmConnection))
{
var queryResult = (from listMember in orgContext.CreateQuery<ListMember>()
where listMember.EntityId.Id == leadId
select listMember).ToList();
if (queryResult.Any())
{
listIds.AddRange(queryResult.Select(x => x.ListId.Id));
}
}
return listIds;
}
}
}