Tuesday, March 26, 2013

Get related entities from Many to many relation CRM 2011

I had a request to obtain all related entities from N:N relation for a specific entity in this relation. There might be other ways to achieve this but this method I used and it worked for me, so I thought to share it with you in case somebody else will need it.

This is the function that returns the a collection of entities for a specific entity from this relation.


 /// <summary>
        /// get entities from many to many relation
        /// </summary>
        /// <param name="entityToRetrieve">the entity name that we want to retrieve</param>
        /// <param name="relationName">relation name</param>
        /// <param name="targetEntity">entity name</param>
        /// <param name="service"></param>
        /// <returns>collection of entities</returns>
        public static DataCollection<Entity> GetRelatedEntitDataFromManyToManyRelation(string entityToRetrieve, string[] columnsToRetieve, string relationName, EntityReference targetEntity, IOrganizationService service)
        {
            DataCollection<Entity> result = null;
         
                QueryExpression query = new QueryExpression();
                query.EntityName = entityToRetrieve;
                query.ColumnSet = new ColumnSet(columnsToRetieve);
                Relationship relationship = new Relationship();

                relationship.SchemaName = relationName;

                RelationshipQueryCollection relatedEntity = new RelationshipQueryCollection();
                relatedEntity.Add(relationship, query);
                RetrieveRequest request = new RetrieveRequest();
                request.RelatedEntitiesQuery = relatedEntity;
                request.ColumnSet = new ColumnSet(targetEntity.LogicalName + "id");
                request.Target = targetEntity;
                RetrieveResponse response = (RetrieveResponse)service.Execute(request);


                if (((DataCollection<Relationship, EntityCollection>)(((RelatedEntityCollection)(response.Entity.RelatedEntities)))).Contains(new Relationship(relationName)) && ((DataCollection<Relationship, EntityCollection>)(((RelatedEntityCollection)(response.Entity.RelatedEntities))))[new Relationship(relationName)].Entities.Count > 0)
                {
                    result = ((DataCollection<Relationship, EntityCollection>)(((RelatedEntityCollection)(response.Entity.RelatedEntities))))[new Relationship(relationName)].Entities;
                }
         
            return result;
        }


You can call this function is like this:
var relatedAccountsForTarget = GetRelatedEntitDataFromManyToManyRelation("account", new string[]{ "accountid" }, "Type here relationName", targetEntity.ToEntityReference(), utils.Service);

4 comments:

  1. Hi Bogdan

    Would you be able to explain me what the following lines does ? Iam trying to understand the code.


    "((DataCollection)(((RelatedEntityCollection)(response.Entity.RelatedEntities))))[new Relationship(relationName)].Entities;"


    Many Thanks

    ReplyDelete
    Replies
    1. Hi STC,

      One thing is that you typed a little differently the code than the one form my example (I have this DataCollection you don;t have it)...
      I'll try to descrive you the idea (now that I look there might be some extra "(" in the example that's why you might be confused...).
      The idea was to obtain a collection of Entities and that was the way I found at that time (had some deadline and the code was a little messy)..

      - First we get the response: response.Entity.RelatedEntities
      - Second we cast it to RelatedEntityCollection
      - Next the RelatedEntityCollection we cast it to DataCollection
      - From obtained DataCollection we get only the entities related to our relationship "[new Relationship(relationName)].Entities".

      Code (just to have an idea):
      var res1= response.Entity.RelatedEntities;
      var res2 = (RelatedEntityCollectio)res1 ;
      var res3 = (DataCollection)res2;
      var resfinal = res3[new Relationship(relationName)].Entities;

      Hope this helps.

      Thanks,
      ---Bogdan

      Delete
    2. I just noticed that "<" and ">" are encoded so
      var res3 = (DataCollection)res2;
      should have been:
      var res3 = (DataCollection"<"Relationship, EntityCollection">")res2;

      Delete
  2. Simplier: response.Entity.RelatedEntities[new Relationship(relationName)].Entities

    ReplyDelete