Answered by:
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 helpfulTuesday, 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 helpspublic 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; }
- Marked as answer by George DoubinskiMVP, Moderator Wednesday, March 17, 2010 1:06 PM
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.comTuesday, March 16, 2010 8:24 PMModerator -
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 helpspublic 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; }
- Marked as answer by George DoubinskiMVP, Moderator Wednesday, March 17, 2010 1:06 PM
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 8, 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 twitterWednesday, September 8, 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.comWednesday, September 8, 2010 10:30 PMModerator