none
Checking if a Many-To-Many relationship exists before creating it in a plugin

    Question

  • Ok, here's my situation.  I've racked my brain and checked every blog, discussion forum and book I can get my hands up.  Hoping and praying someone here can help. 

    Ok, the situation is this.  I have a custom entity and it has an N:1 relationship with all the activities and a many to many relationship with the Contact.  The idea is this roughly:

    The user clicks to create a new activity (task, phone call, whatever)...And selects from a lookup a contact (John Smith) and selects from the custom entity lookup(Custom1).  They then hit save and close.

    I have built a plugin that runs on the PostCreate event, that says ok, do the following:
    Update the category of the activity to say "CustomUsed", for making advanced find easier.
    Create an instance of the many-to-many relationship(new_customContact) between John Smith and Custom1.

    I have that all working, using dynamic entities and everything it works great.  There's only one problem.  If John Smith and Custom1 already have an instance of the relationship new_customContact, it throws an errors cause obviously it can't make duplicate relationships.  So I need to check and make sure it doesn't exist before I create it.

    Still with me?  I built the method below after reading up on retrieveMultiple, but whenever I use it I get an error saying "Invalid Recipient Type".  Any help or thoughts would be great.  In documentation above I listed what is being passed to the method.
    //returnAttribute = contactid and new_customid
    //filterAttribute1 = contactid
    //filterattribute2 = new_customid
    //filterValue1 = (GUID) of contact
    //filterValue2 = (GUID) of custom
    //ConOperator = ConditionOperator.Equal
    //entityName = Relationship Entity Name
    //service = CRM Service created from context
    
    public static BusinessEntityCollection GetManyToManyCollection(
                string[] returnAttribute, 
                string filterAttribute1,
                string filterAttribute2,
                string filterValue1, 
                string filterValue2,
                ConditionOperator ConOperator, 
                string entityName, 
                ICrmService service)
            {
                ConditionExpression con1 = new ConditionExpression();
                con1.AttributeName = filterAttribute1;
                con1.Operator = ConOperator;
                con1.Values = new string[] { filterValue1 };
    
                ConditionExpression con2 = new ConditionExpression();
                con2.AttributeName = filterAttribute2;
                con2.Operator = ConOperator;
                con2.Values = new string[] { filterValue2 };
    
                FilterExpression filter = new FilterExpression();
                filter.FilterOperator = LogicalOperator.And;
                filter.Conditions.Add(con1);
                filter.Conditions.Add(con2);
    
                QueryExpression query = new QueryExpression();
                query.EntityName = entityName;
                query.ColumnSet = new ColumnSet(returnAttribute);
                query.Criteria = filter;
                
                RetrieveMultipleRequest request = new RetrieveMultipleRequest();
                request.Query = query;
                request.ReturnDynamicEntities = true;
    
                BusinessEntityCollection response = (BusinessEntityCollection)service.Execute(request);
                BusinessEntityCollection results = response;
                return results;
            }
    Ok, so I've used the relationship entity name that is specificed, and I have a feeling that might have something to do with it.  But basically I was going to take the results of this and if the count > 0 then don't create.

    Any thoughts are helpful
    Tuesday, March 16, 2010 8:10 PM

Answers

  • Hi,

    Please check following blog for the same

    http://blogs.msdn.com/crm/archive/2008/02/14/crm-4-0-relationships-explained.aspx


    I am also proving example code for this ..Hope this helps

    public bool  IsRelationshipAlreadyExist(CrmService myService, string oppId, string otherId)
            {
                bool isAlreadyExist = false;
    
                ConditionExpression conditionOppId = new ConditionExpression();
                conditionOppId.AttributeName = "opportunityid";
                conditionOppId.Operator = ConditionOperator.Equal;
                conditionOppId.Values = new object[1];
                conditionOppId.Values[0] = oppId;
    
                FilterExpression selectByOppId = new FilterExpression();
                selectByOppId.Conditions = new ConditionExpression[] { conditionOppId };
              
                //Create nested link entity and apply filter criteria 
                LinkEntity nestedLinkEntity = new LinkEntity();
                nestedLinkEntity.LinkToEntityName = EntityName.opportunity.ToString();   
                nestedLinkEntity.LinkFromAttributeName = "opportunityid";
                nestedLinkEntity.LinkToAttributeName = "opportunityid";
                nestedLinkEntity.LinkCriteria = selectByOppId;
    
                ConditionExpression conditionAreaId = new ConditionExpression();
                conditionAreaId.AttributeName = <<OTHER ID>>;
                conditionAreaId.Operator = ConditionOperator.Equal;
                conditionAreaId.Values = new object[1];
                conditionAreaId.Values[0] = otherId;
    
                FilterExpression selectByAreaId = new FilterExpression();
                selectByAreaId.Conditions = new ConditionExpression[] { conditionAreaId };
    
                //Create the nested link entities
                LinkEntity intersectEntity = new LinkEntity();
                intersectEntity.LinkToEntityName = <<Relationship name >>; 
                intersectEntity.LinkFromAttributeName = <<OTHER ID>>;
                intersectEntity.LinkToAttributeName = <<OTHER ID>>;
                intersectEntity.LinkEntities = new LinkEntity[] { nestedLinkEntity };
    
                //Create Query expression and set the entity type to lead 
                QueryExpression expression = new QueryExpression();
                expression.EntityName = <<OTHER ENTITY NAME>>;   
                expression.LinkEntities = new LinkEntity[] { intersectEntity };
                expression.Criteria = selectByAreaId;
    
                RetrieveMultipleRequest request = new RetrieveMultipleRequest();
                request.Query = expression;            
                
                //Execute and examine the response             
                RetrieveMultipleResponse response = (RetrieveMultipleResponse)myService.Execute(request);
                //BusinessEntity[] entities = response.BusinessEntityCollection.BusinessEntities;
    
                if (response.BusinessEntityCollection.BusinessEntities.Length > 0)
                {
                    isAlreadyExist = true;
                }
                //Console.WriteLine("Total related=" + entities.Length);
    
                return isAlreadyExist;
            }
    Tuesday, March 16, 2010 8:30 PM

All replies

  • I think this should be  RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);

    but not sure if this is causing your error. Debug your code and see if service.Execute(request); actually returns anything or throws the exception.


    MSCRM Bing'd - http://bingsoft.wordpress.com
    Tuesday, March 16, 2010 8:24 PM
    Moderator
  • Hi,

    Please check following blog for the same

    http://blogs.msdn.com/crm/archive/2008/02/14/crm-4-0-relationships-explained.aspx


    I am also proving example code for this ..Hope this helps

    public bool  IsRelationshipAlreadyExist(CrmService myService, string oppId, string otherId)
            {
                bool isAlreadyExist = false;
    
                ConditionExpression conditionOppId = new ConditionExpression();
                conditionOppId.AttributeName = "opportunityid";
                conditionOppId.Operator = ConditionOperator.Equal;
                conditionOppId.Values = new object[1];
                conditionOppId.Values[0] = oppId;
    
                FilterExpression selectByOppId = new FilterExpression();
                selectByOppId.Conditions = new ConditionExpression[] { conditionOppId };
              
                //Create nested link entity and apply filter criteria 
                LinkEntity nestedLinkEntity = new LinkEntity();
                nestedLinkEntity.LinkToEntityName = EntityName.opportunity.ToString();   
                nestedLinkEntity.LinkFromAttributeName = "opportunityid";
                nestedLinkEntity.LinkToAttributeName = "opportunityid";
                nestedLinkEntity.LinkCriteria = selectByOppId;
    
                ConditionExpression conditionAreaId = new ConditionExpression();
                conditionAreaId.AttributeName = <<OTHER ID>>;
                conditionAreaId.Operator = ConditionOperator.Equal;
                conditionAreaId.Values = new object[1];
                conditionAreaId.Values[0] = otherId;
    
                FilterExpression selectByAreaId = new FilterExpression();
                selectByAreaId.Conditions = new ConditionExpression[] { conditionAreaId };
    
                //Create the nested link entities
                LinkEntity intersectEntity = new LinkEntity();
                intersectEntity.LinkToEntityName = <<Relationship name >>; 
                intersectEntity.LinkFromAttributeName = <<OTHER ID>>;
                intersectEntity.LinkToAttributeName = <<OTHER ID>>;
                intersectEntity.LinkEntities = new LinkEntity[] { nestedLinkEntity };
    
                //Create Query expression and set the entity type to lead 
                QueryExpression expression = new QueryExpression();
                expression.EntityName = <<OTHER ENTITY NAME>>;   
                expression.LinkEntities = new LinkEntity[] { intersectEntity };
                expression.Criteria = selectByAreaId;
    
                RetrieveMultipleRequest request = new RetrieveMultipleRequest();
                request.Query = expression;            
                
                //Execute and examine the response             
                RetrieveMultipleResponse response = (RetrieveMultipleResponse)myService.Execute(request);
                //BusinessEntity[] entities = response.BusinessEntityCollection.BusinessEntities;
    
                if (response.BusinessEntityCollection.BusinessEntities.Length > 0)
                {
                    isAlreadyExist = true;
                }
                //Console.WriteLine("Total related=" + entities.Length);
    
                return isAlreadyExist;
            }
    Tuesday, March 16, 2010 8:30 PM
  • Hi,

     How to iterate the entities object? 

    RetrieveMultipleResponse response = (RetrieveMultipleResponse)_crmService.Execute(request);
    
            BusinessEntity[] entities = response.BusinessEntityCollection.BusinessEntities;
    

    Wednesday, September 08, 2010 12:54 AM
  • you do this using following syntax...asumming you arer returning account entity following is syntax for the same,,,

    foreach (BusinessEntity be in res.BusinessEntityCollection.BusinessEntities)
                        {
                            account myAccount = (account)be;
                        }

     


    MayankP My Blog My twitter
    Wednesday, September 08, 2010 8:41 AM
  • I've written some new utility code for expressly this purpose:  http://crmentropy.blogspot.com/2010/09/nn-relationship-utility-code-javascript.html
    Dave Berry - MVP Dynamics CRM - http:\\crmentropy.blogspot.com
    Wednesday, September 08, 2010 10:30 PM
    Moderator