I'm working on a C# application for merging duplicate Accounts in Dynamics CRM. In it I have checks on each of the fields that are part of the merge. It had been executing correctly, but then I ran into an instance where a lookup on the target record was not populated.
The check is written like this:
if (!masterAccount.Contains("new_membership")
&& subOrdinateAccount.Contains("new_membership"))
{
updateContent.Attributes.Add("new_membership", subOrdinateAccount.Attributes["new_membership"]);
}
I can see that the attribute is being returned correctly for the subOrdinateAccount, and the if does not return an error. However, later on in the code an exception is thrown. This is the line:
MergeResponse mergeRes = (MergeResponse)xrm.Execute(merge);
This is the exception:
An unhandled exception of type 'System.ServiceModel.FaultException`1' occurred in Microsoft.Xrm.Sdk.dll Additional information: Cannot specify child attributes in the columnset for Retrieve. Attribute: new_membershipname
One thing I noticed is that it added "name" to the end of the lookup field.
Is this because it is looking for a different text value, rather than the returned object value?
Here is the full code :
using System;
using System.Data.Entity;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Xml.Linq;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using Xrm;
using Microsoft.Crm.Sdk.Messages;
using System.Threading;
namespace Duplicate_Account_Merge
{
class Program
{
static void Main(string[] args)
{
XrmServiceContext xrm = new XrmServiceContext("Xrm");
Guid masterAccountId;
Guid subOrdinateAccountId;
//Create the target for the request.
EntityReference target = new EntityReference();
// Query for Accounts
var accounts = (from a in xrm.AccountSet.ToList()
where a.StateCode != 1 && a.Name != null
group a by a.Name into g
where g.Count() > 1
from a2 in xrm.AccountSet.ToList()
where a2.StateCode != 1
where a2.Name == g.Key
orderby a2.Name, a2.CreatedOn descending
select new
{
a2.Name,
//a2.LastName,
//a2.EMailAddress1,
a2.AccountId,
a2.CreatedOn
}).ToList();
int count = 0;
int mergeCount = 0;
while (accounts.Count != 0 && accounts.Count != 1)
{
if (accounts.Count > 1 && accounts[0].Name == accounts[1].Name)
{
masterAccountId = accounts[0].AccountId.Value;
subOrdinateAccountId = accounts[1].AccountId.Value;
//target,Id is the GUID of the contact that is being merged into.
//LogicalName is the type of the entity being merged to, as a string
target.Id = masterAccountId;
target.LogicalName = "account";
//Create the request.
MergeRequest merge = new MergeRequest();
// SubordinateId is the GUID of the contact merging.
merge.SubordinateId = subOrdinateAccountId;
merge.Target = target;
merge.PerformParentingChecks = false;
Entity updateContent = new Entity("account");
var accountcolumnset = new ColumnSet(
"name",
"accountnumber",
"new_membership",
//"parentaccountid",
"new_acronym",
"new_category",
"new_sortname",
"new_membertype",
"new_foundationtype",
"new_focusarea",
"new_focusarea2",
"new_focusarea3",
"new_100aging",
"new_isamember",
// Contacts section
"new_grantscontact",
"new_membershipcontact",
"msa_managingpartnerid",
"primarycontactid",
// Contact Information section
"address1_name",
"address1_composite",
"telephone1",
"websiteurl",
"emailaddress1",
// Details tab
// Contact Preferences section
"preferredcontactmethodcode",
"donotphone",
"donotpostalmail",
// Marketing section
"donotsendmm",
"lastusedincampaign",
// Description section
"description"
);
// Get Master Account Primary Contact,Website,Phone,Fax,Email
Entity masterAccount = xrm.Retrieve("account", masterAccountId, accountcolumnset);
// Get Subordinate Account Primary Contact,Website,Phone,Fax,Email
Entity subOrdinateAccount = xrm.Retrieve("account", subOrdinateAccountId, accountcolumnset);
// UPDATE THESE IFS WITH FIELD VALUES FROM THE COLUMN SET
// If these fields are populated on the Subordinate Account and NOT populated on the Master Account, update the Master record with values from the suboordinate.
if (!masterAccount.Contains("accountnumber") && subOrdinateAccount.Contains("accountnumber"))
updateContent.Attributes.Add("accountnumber", subOrdinateAccount.Attributes["accountnumber"]);
if (!masterAccount.Contains("new_membership") && subOrdinateAccount.Contains("new_membership"))
updateContent.Attributes.Add("new_membership", subOrdinateAccount.Attributes["new_membership"]);
//updateContent.Attributes.Add("primarycontactid", new EntityReference("contact", subOrdinateContact.GetAttributeValue<EntityReference>("primarycontactid").Id));
//if (!masterAccount.Contains("parentaccountid") && subOrdinateAccount.Contains("parentaccountid"))
// updateContent.Attributes.Add("parentaccountid", subOrdinateAccount.Attributes["parentaccountid"]);
if (!masterAccount.Contains("new_acronym") && subOrdinateAccount.Contains("new_acronym"))
updateContent.Attributes.Add("new_acronym", subOrdinateAccount.Attributes["new_acronym"]);
if (!masterAccount.Contains("new_category") && subOrdinateAccount.Contains("new_category"))
updateContent.Attributes.Add("new_category", subOrdinateAccount.Attributes["new_category"]);
if (!masterAccount.Contains("new_sortname") && subOrdinateAccount.Contains("new_sortname"))
updateContent.Attributes.Add("new_sortname", subOrdinateAccount.Attributes["new_sortname"]);
if (!masterAccount.Contains("new_membertype") && subOrdinateAccount.Contains("new_membertype"))
updateContent.Attributes.Add("new_membertype", subOrdinateAccount.Attributes["new_membertype"]);
if (!masterAccount.Contains("new_foundationtype") && subOrdinateAccount.Contains("new_foundationtype"))
updateContent.Attributes.Add("new_foundationtype", subOrdinateAccount.Attributes["new_foundationtype"]);
if (!masterAccount.Contains("new_focusarea") && subOrdinateAccount.Contains("new_focusarea"))
updateContent.Attributes.Add("new_focusarea", subOrdinateAccount.Attributes["new_focusarea"]);
if (!masterAccount.Contains("new_focusarea2") && subOrdinateAccount.Contains("new_focusarea2"))
updateContent.Attributes.Add("new_focusarea2", subOrdinateAccount.Attributes["new_focusarea2"]);
if (!masterAccount.Contains("new_focusarea3") && subOrdinateAccount.Contains("new_focusarea3"))
updateContent.Attributes.Add("new_focusarea3", subOrdinateAccount.Attributes["new_focusarea3"]);
if (!masterAccount.Contains("new_100aging") && subOrdinateAccount.Contains("new_100aging"))
updateContent.Attributes.Add("new_100aging", subOrdinateAccount.Attributes["new_100aging"]);
if (!masterAccount.Contains("new_isamember") && subOrdinateAccount.Contains("new_isamember"))
updateContent.Attributes.Add("new_isamember", subOrdinateAccount.Attributes["new_isamember"]);
// Contact Information section
if (!masterAccount.Contains("address1_name") && subOrdinateAccount.Contains("address1_name"))
updateContent.Attributes.Add("address1_name", subOrdinateAccount.Attributes["address1_name"]);
if (!masterAccount.Contains("address1_composite") && subOrdinateAccount.Contains("address1_composite"))
updateContent.Attributes.Add("address1_composite", subOrdinateAccount.Attributes["address1_composite"]);
if (!masterAccount.Contains("telephone1") && subOrdinateAccount.Contains("telephone1"))
updateContent.Attributes.Add("telephone1", subOrdinateAccount.Attributes["telephone1"]);
if (!masterAccount.Contains("websiteurl") && subOrdinateAccount.Contains("websiteurl"))
updateContent.Attributes.Add("websiteurl", subOrdinateAccount.Attributes["websiteurl"]);
if (!masterAccount.Contains("emailaddress1") && subOrdinateAccount.Contains("emailaddress1"))
updateContent.Attributes.Add("emailaddress1", subOrdinateAccount.Attributes["emailaddress1"]);
// Details tab
// Contact Preferences section
if (!masterAccount.Contains("preferredcontactmethodcode") && subOrdinateAccount.Contains("preferredcontactmethodcode"))
updateContent.Attributes.Add("preferredcontactmethodcode", subOrdinateAccount.Attributes["preferredcontactmethodcode"]);
if (!masterAccount.Contains("donotphone") && subOrdinateAccount.Contains("donotphone"))
updateContent.Attributes.Add("donotphone", subOrdinateAccount.Attributes["donotphone"]);
if (!masterAccount.Contains("donotpostalmail") && subOrdinateAccount.Contains("donotpostalmail"))
updateContent.Attributes.Add("donotpostalmail", subOrdinateAccount.Attributes["donotpostalmail"]);
// Marketing section
if (!masterAccount.Contains("donotsendmm") && subOrdinateAccount.Contains("donotsendmm"))
updateContent.Attributes.Add("donotsendmm", subOrdinateAccount.Attributes["donotsendmm"]);
if (!masterAccount.Contains("emailaddress1") && subOrdinateAccount.Contains("emailaddress1"))
updateContent.Attributes.Add("emailaddress1", subOrdinateAccount.Attributes["emailaddress1"]);
if (!masterAccount.Contains("fax") && subOrdinateAccount.Contains("fax"))
updateContent.Attributes.Add("fax", subOrdinateAccount.Attributes["fax"]);
// Description section
if (!masterAccount.Contains("preferredcontactmethodcode") && subOrdinateAccount.Contains("preferredcontactmethodcode"))
updateContent.Attributes.Add("preferredcontactmethodcode", subOrdinateAccount.Attributes["preferredcontactmethodcode"]);
// Contacts section
if (!masterAccount.Contains("new_grantscontact") && subOrdinateAccount.Contains("new_grantscontact"))
updateContent.Attributes.Add("new_grantscontact", subOrdinateAccount.Attributes["new_grantscontact"]);
if (!masterAccount.Contains("new_membershipcontact") && subOrdinateAccount.Contains("new_membershipcontact"))
updateContent.Attributes.Add("new_membershipcontact", subOrdinateAccount.Attributes["new_membershipcontact"]);
if (!masterAccount.Contains("msa_managingpartnerid") && subOrdinateAccount.Contains("msa_managingpartnerid"))
updateContent.Attributes.Add("msa_managingpartnerid", subOrdinateAccount.Attributes["msa_managingpartnerid"]);
if (!masterAccount.Contains("primarycontactid") && subOrdinateAccount.Contains("primarycontactid"))
updateContent.Attributes.Add("primarycontactid", subOrdinateAccount.Attributes["primarycontactid"]);
merge.UpdateContent = updateContent;
// Execute the request.
MergeResponse mergeRes = (MergeResponse)xrm.Execute(merge);
count++;
mergeCount++;
Console.WriteLine("Merge #"
+ mergeCount
+ "\n"
+ "Master Account: "
+ accounts[0].Name
+ " "
+ accounts[0].AccountId
+ "\n"
+ "Child Account: "
+ accounts[1].Name
+ " "
+ accounts[1].AccountId);
accounts.RemoveAt(1);
}
else
{
if (accounts.Count > 2 && accounts.Count != 1 && accounts.Count != 0)
accounts.RemoveAt(0);
}
}
Console.ReadLine();
}
}
}
Make sure you give an EntityReference
object to the updateContent.Attributes.Add()
method for new_membership
attribute.
You could also try explicitly giving in the name; something like
updateContent.Attributes.Add("new_membershipname", ((EntityReference)subOrdinateAccount.Attributes["new_membership"]).Name);