Microsoft Dynamics CRM Many to Many Relationships – Workflow challenge, Part 1

clock on track

I was recently tasked with developing a workflow against a many to many relationship in an already highly customized and active Microsoft Dynamics CRM organization.  The workflow needed to share Accounts with specific users based on their association with a Parent entity linked via a many to many relationship.  In addition, Accounts could be linked/unlinked to the parent entities at any time, so I needed to ensure that the workflow maintained accurate shared rights to the Accounts throughout the day.  To accomplish this, there were a few challenges that I needed to tackle.

The first challenge was, what will trigger the workflow?  You cannot trigger workflows from a many to many relationship in Microsoft Dynamics CRM, so I needed to find a way around this.

Since this organization was already using the Account to Parent entity relationship, I was limited with what new customizations I could add.  I ended up creating a new one to many relationship between the User entity and the Parent entity.  This initially was added just to allow the end user to set up the security model, but this also ended up serving as the trigger for the workflow.  So when a user is linked to a Parent entity, the workflow will trigger once against the Parent entity and share the child Accounts to the user.  In order to maintain the end users shared rights to those Accounts, I coded some logic within my workflow using a combination of output parameters and the native workflow interface to repeat the workflow during critical business times of the day.

Here is an example: I needed the workflow to run daily at 9AM.  I coded one output parameter that tells the workflow how many hours remain until 9AM. Within the CRM workflow interface I set it to timeout until HoursUntil9AM and then repeat itself as a child workflow:

if ((DateTime.UtcNow.ToLocalTime().Hour) < 9)


DateTime date = new DateTime(DateTime.Today.ToLocalTime().Year, DateTime.Today.ToLocalTime().Month, DateTime.Today.ToLocalTime().Day);

TimeSpan time = new TimeSpan(9, 00, 0);

date = date.Date + time;

HoursUntil9AM.Set(executionContext, date);


In addition to the above, I enabled the workflow to run on demand to give admins the ability to manually trigger the workflow at any time during the day.

In part 2 of this blog I will discuss how I tackled challenges related to performance for sharing and unsharing of records.

Beringer is a Microsoft Gold Certified Partner. We are here to provide solutions to your problems. Please contact Beringer today!