Reputation: 195
Sometimes I need to delete a duplicate record in CRM that has associations. In these cases I have to reassign these associations. The related entities menu allows me to check, one by one, whether the record has associations in any of the entities to which it is related. This forces me to scan through many related entities. Is there a quicker way to view all associations for a record?
Upvotes: 2
Views: 3770
Reputation: 136
I know this question is old, but I created a console app that will show related GUIDs and logical names of the associated records. Currently doesn't work with Many to Many relationships because it wasn't needed for my application. It could easily be made to show links to records, but it wasn't something I needed.
static void Main(string[] args)
{
IOrganizationService OrganizationService = null;
string sourceBaseUrl = "http://server/org";
OrganizationService = CrmHelpers.GetService(sourceBaseUrl);
//OrganizationService = CrmHelpers.GetService("sock-devcrm2015", "acs-training", "80", "http", "username", "password", "domain");
//query for relationships for the desired record
//need to get GUID and LogicalName
Entity get = new Entity();
Console.WriteLine(string.Format("What is the Logical Name?"));
Console.Write("String: ");
get.LogicalName = Console.ReadLine();
Console.WriteLine(string.Format("What is the GUID?"));
Console.Write("GUID: ");
get.Id = Guid.Parse(Console.ReadLine());
RetrieveEntityRequest retrieveEntity = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.Relationships,
LogicalName = get.LogicalName
};
RetrieveEntityResponse response = (RetrieveEntityResponse)OrganizationService.Execute(retrieveEntity);
var oneToN = response.EntityMetadata.OneToManyRelationships;
var nToOne = response.EntityMetadata.ManyToOneRelationships;
foreach (var relationship in oneToN)
{
string fetch = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='" + relationship.ReferencingEntity + @"'>
<filter type='and'>
<condition attribute='" + relationship.ReferencingAttribute + @"' operator='eq' value='" + get.Id.ToString() + @"' />
</filter>
</entity>
</fetch>";
var results = OrganizationService.RetrieveMultiple(new FetchExpression(fetch));
foreach (var result in results.Entities)
{
Console.WriteLine(string.Format("1:N || GUID: {0} LogicalName: {1}", result.Id, result.LogicalName));
}
}
Console.WriteLine("----------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------");
foreach (var relationship in nToOne)
{
string fetch = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='" + relationship.ReferencedEntity + @"'>
<link-entity name='"+relationship.ReferencingEntity+ @"' from='"+relationship.ReferencingAttribute+@"' to='"+relationship.ReferencedAttribute+@"' alias='a'>
<filter type='and'>
<condition attribute='" + get.LogicalName+ @"id' operator='eq' value='" + get.Id.ToString() + @"' />
</filter>
</link-entity>
</entity>
</fetch>";
var results = OrganizationService.RetrieveMultiple(new FetchExpression(fetch));
foreach (var result in results.Entities)
{
Console.WriteLine(string.Format("N:1 || GUID: {0} LogicalName: {1}", result.Id, result.LogicalName));
}
}
Console.Write("END");
Console.ReadLine();
}
class CrmHelpers
{
public static IOrganizationService GetService(string baseUrl)
{
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = CredentialCache.DefaultCredentials.GetCredential(new Uri(baseUrl), "negotiate");
Uri endpoint = new Uri(string.Format("{0}/XRMServices/2011/Organization.svc", baseUrl));
OrganizationServiceProxy service = new OrganizationServiceProxy(endpoint, null, credentials, null);
service.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
return service;
}
}
Upvotes: 1
Reputation: 1
All the N:1 relationships can be found by querying the filtered view for your entity in SQL, but the fastest solution is just to use the Merge functionality built into CRM, as suggested. It doesn't delete the dupe, but it deactivates it and assigns everything you specify to the 'master' record. From there, you can delete the deactivated record.
Upvotes: 0
Reputation: 17562
You could make a new record form which shows all the associated record as sub grids on a single page - might save a few clicks.
Few considerations with this approach:
Upvotes: 4
Reputation: 21
If you need to reassign all the associations, this would work:
You just cloned a record and the new one will have all the associations from the old one.
Upvotes: 0
Reputation: 795
Not through the CRM UI, but if you're a SQL Wizard, you could probably come up with some fancy query to do that. Then you could deploy an SSRS report with click through if you want to take it one step further.
You should also consider the OOB Merge for a scenario like this if you are dealing with OOB records like contacts or accounts - as this will automatically reparent child records for you (granted it will reparent all the child records to the new "master" record, but that is usually the intended functionality, so it works in most cases).
Upvotes: 1