Associate/Disassociate plugin messages in CRM
In CRM, the Associate or Disassociate event happens
- If you have a N:N relationship between two entities and when you try to associate or disassociate records either from Associated view or Sub grid.
In Plugins, the Associate & Disassociate messages behave little different than other messages.
- When you register a plugin on Associate message, you have to leave “Primary and Secondary” entities as ‘none’.
- Since we don’t provide entity names, the registered Plug-in step triggers on all “Associate” operations, so we have to check few conditions to let the “Association” trigger happen only between intended entities.
You can use the below code template for Associate or Disassociate plugins
EntityReference targetEntity = null;
string relationshipName = string.Empty;
EntityReferenceCollection relatedEntities = null;
EntityReference relatedEntity = null;
if (context.MessageName == “Associate”) {
// Get the “Relationship” Key from context
if (context.InputParameters.Contains(“Relationship”)) {
relationshipName = context.InputParameters[“Relationship”].ToString();
}
// Check the “Relationship Name” with your intended one
if (relationshipName != “{YOUR RELATION NAME}”) {
return;
}
// Get Entity 1 reference from “Target” Key from context
if (context.InputParameters.Contains(“Target”) && context.InputParameters[“Target”] is EntityReference) {
targetEntity = (EntityReference)context.InputParameters[“Target”];
}
// Get Entity 2 reference from ” RelatedEntities” Key from context
if (context.InputParameters.Contains(“RelatedEntities”) && context.InputParameters[“RelatedEntities”] is EntityReferenceCollection) {
relatedEntities = context.InputParameters[“RelatedEntities”] as EntityReferenceCollection;
relatedEntity = relatedEntities[0];
}
}
🙂
Thanks for the tip. However, as far as I can tell, your expression does not work correctly:
relationshipName = context.InputParameters[“Relationship”].ToString()
This expression does not yield the relationship name. It just returns the string ‘Microsoft.Xrm.Sdk.Relationship’. Instead, you need:
relationshipName = ((Relationship) context.InputParameters[“Relationship”]).SchemaName
(I am in CRM 2015, but the APIs seem to be virtually the same.)
Thanks for the update.
Will this work 1: N relationship. Please confirm?
Associate\Disassociate is only for N:N relationship. For 1:N you can use Update Message, if you want to trigger a Plug-in when Primary Record changes by keeping Lookup field as ‘Filtering Attribute’
When i put a plugin with a step associate or dissociate it don’t activate itself when i link two entities. have i misunderstande this event?
Suppose i have a custom entity Registration and Individuals and I have N:N relationship created. Below is my sample code not yet used in my plugin.
public static void AssociateIndividualsToRegistration(EntityReference individual, EntityReference registration, IOrganizationService service)
{
//Create EntityReferenceCollection for Individuals
EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
//Add the related entity Individuals
relatedEntities.Add(individual);
//Add the Registration Individual relationship schema name
Relationship relationship = new Relationship(“poc_registration_individual”);
//Associate the Individual record to Registration
service.Associate(registration.LogicalName, registration.Id, relationship, relatedEntities);
}
Since I have never used Associate message, am curious to what does associate plugin will do exactly
For. eg.
Create message – when you create a new record and save.(do something)
Update message – when you update any fields on the form and save.(do something)
Delete message – when you delete a record or child record from subgrid(do something)
Similarly
associate message – when this will be triggered? I have the individual lookup field in Registration entity. I also see that when I save the registration record with individual lookup value selected. I see this record in registration entity associated view.
Please help me understanding the associate/disassociate plugin of CRM.
Regards,
Ganesh A
Associate – Triggers when you associate ‘Registration’ and ‘Individual’ (i.e., When you go to Associated View grid of either ‘Registration’ or ‘Individual’ and click ‘Add Existing button’)
Disassociate – Triggers when you remove either ‘Registration’ or ‘Individual’ records from Associated View grid.
thanks a lot Rajeev you are amazing developer
Thanks for your blog post. Like Claus, I also had a problem with ToString() – however, it’s a different problem. I’m on Microsoft Dynamics 365 Version 1612 (8.2.1.271) (DB 8.2.1.271) online, and
context.InputParameters[“Relationship”].ToString()
gives me the real relationship name followed by a period. This was hard to catch since it looked right at a quick glance!
May I suggest you update your original post with Claus’ fix? That could save people some time in the future 🙂
Thanks for feedback. But I could not find any discrepancy.
do we need to register the inout parameter anywhere?
Hello Rajeev,
I have a usecase where i would like to implement your strategy. I want to have a webhook with the “Associate” message handler who will redirect to a custom api i will build. This api would do some calculations and make some updates on some Dataverse entities. My question is where you should implement the code so it only triggers on a certain relation name.
In your Azure function, you can either use
-> string jsonPluginContext=await httpRequest.Content.ReadAsStringAsync();
or
-> Use RemoteExecutionContext class (https://msdynamicscrm137374033.wordpress.com/2019/11/03/azure-function-integration-ms-dynamics-crm-using-remote-execution-context/) statements to read the Plug-in Context.
Once you have Plug-in Context, you can use check as following:
if (context.InputParameters.Contains(“Relationship”)) {
relationshipName = context.InputParameters[“Relationship”].ToString();
}
// Check the “Relationship Name” with your intended one
if (relationshipName != “{YOUR RELATION NAME}”) {
return;
}