This project has moved. For the latest updates, please go here.
1

Closed

Issue with Associate Entity

description

Hello,

I recently tried to use the Associate Entity workflow activity, but I ran into a problem where the workflow would fire but the relationship would not be created. After some investigation, I discovered an issue with the getAssociations method in Common.cs.

In this method, you create a fetchXML statement that returns the number of relationships between the primary entity and a particular parent entity ID. In AssociateEntity.cs, you take the result and only associate if count == 0. However, this fetchXML statement doesn't return the relationships between a particular primary entity ID and a particular parent entity ID, but between all the primary entities and a particular parent entity ID.

Consider the following situation:

I have Opportunities A, B, and C and Competitor A.
I have an N:N relationship between Opportunities and Competitors called opportunitycompetitors_association.
Opportunity A is associated with Competitor A.

If I fire a workflow on Opportunity B and try to associate Opportunity B with Competitor A, getAssociations will use the following fetchXML:

<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='opportunity'>
<link-entity name='opportunitycompetitors_association' from='opportunityid' to='opportunityid' visible='false' intersect='true'>
<link-entity name='competitor' from='competitorid' to='competitorid' alias='ac'>
<filter type='and'>
<condition attribute='competitorid' operator='eq' value='{GUID for Competitor A}' />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>

This will return Opportunity A (since it is associated with Competitor A) and since count != 0 AssociateEntity will end without associating Opportunity B to Competitor A.

The fetchXML should instead look like this:


<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='opportunity'>
<link-entity name='opportunitycompetitors_association' from='opportunityid' to='opportunityid' visible='false' intersect='true'>
<link-entity name='opportunity' from='opportunityid' to='opportunityid' alias='ab'>
<filter type='and'>
<condition attribute='opportunityid' operator='eq' value='{GUID for Opportunity B}' />
</filter>
</link-entity>
<link-entity name='competitor' from='competitorid' to='competitorid' alias='ac'>
<filter type='and'>
<condition attribute='competitorid' operator='eq' value='{GUID for Competitor A}' />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>

This will correctly return null and AssociateEntity will create an association between Opportunity B and Competitor A.

Best,
Daniel
Closed Feb 11 at 9:34 PM by demian_rasko

comments

demian_rasko wrote Feb 11 at 9:34 PM

Thank you Daniel for identifying this bug, and to propose the solution.
I just updated the solution with this issue solved as you explained.

Thanks!!

Demian

wrote Feb 11 at 9:34 PM

DanielDix wrote Mar 29 at 11:10 PM

Hello Demian,

I just tested your latest version, but it still doesn't work. After reviewing the code, I think I found the problem:

public EntityCollection getAssociations(string PrimaryEntityName, Guid PrimaryEntityId, string _relationshipName, string _relationshipEntityName, string entityName, string ParentId)
    {
        //
        string fetchXML = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
                                  <entity name='" + PrimaryEntityName + @"'>
                                    <link-entity name='" + _relationshipEntityName + @"' from='" + PrimaryEntityName + @"id' to='" + PrimaryEntityName + @"id' visible='false' intersect='true'>
                                    <link-entity name='opportunity' from='opportunityid' to='opportunityid' alias='ab'>
                                        <filter type='and'>
                                        <condition attribute='opportunityid' operator='eq' value='"+ PrimaryEntityId.ToString()+ @"' />
                                        </filter>
                                    </link-entity>
                                    <link-entity name='" + entityName + @"' from='" + entityName + @"id' to='" + entityName + @"id' alias='ac'>
                                            <filter type='and'>
                                              <condition attribute='" + entityName + @"id' operator='eq' value='" + ParentId + @"' />
                                            </filter>
                                          </link-entity>
                                    </link-entity>
                                  </entity>
                                </fetch>";

        EntityCollection relations = service.RetrieveMultiple(new FetchExpression(fetchXML));

        return relations;
    }
In the getAssociations function, when building the fetchXML, you hard-coded the Opportunity entity:

<condition attribute='opportunityid' operator='eq' value='"+ PrimaryEntityId.ToString()+ @"' />

However, the primary entity could be different. In my company's use case, the Primary Entity Name is "account".

Best,
Daniel