CRM Entity Relationship Many to Many (N:N)
There are two ways of getting the related entity details in many to many relationship in CRM 4.0
One way is to use RetrieveMultipleRequest function from the SDK:
For example, if we have a Loan custom entity and we want to return sets of borrowers (contacts):
---
Second way is to use Fetch function to return the XML of the related entities:
James Downey created a nice little program FetchXMLBuilder to help you build the fetch query.
---
Just for completion, below is the CRMServiceWrapper constructor that I use:
Hope this helps ^_^
One way is to use RetrieveMultipleRequest function from the SDK:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | public BusinessEntityCollection RetrieveEntityCollectionFromManyToMany( string linkTableEntityName, string filterEntityName, string filterEntityIdName, string filterAttribute, string filterValue, string returnedCollectionEntityName, string returnedCollectionEntityIdName, string [] returnedAttributes) { // Selection against linked Filter Entity var con = new ConditionExpression { AttributeName = filterAttribute, Operator = ConditionOperator.Equal, Values = new [] { filterValue } }; var filter = new FilterExpression { FilterOperator = LogicalOperator.And }; filter.AddCondition(con); // the Entity that you are filtering with var filterLinkEntity = new LinkEntity { LinkToEntityName = filterEntityName, LinkFromAttributeName = filterEntityIdName, LinkToAttributeName = filterEntityIdName, LinkCriteria = filter }; // The linktable Entity that CRM generates var linkTableEntity = new LinkEntity { LinkToEntityName = linkTableEntityName, LinkFromAttributeName = returnedCollectionEntityIdName, LinkToAttributeName = returnedCollectionEntityIdName }; linkTableEntity.LinkEntities.Add(filterLinkEntity); // The Entity returning the results var expression = new QueryExpression { EntityName = returnedCollectionEntityName }; // Set columns being returned if (returnedAttributes == null ) { expression.ColumnSet = new AllColumns(); } else { expression.ColumnSet = new ColumnSet(returnedAttributes); } expression.LinkEntities.Add(linkTableEntity); var request = new RetrieveMultipleRequest { Query = expression, ReturnDynamicEntities = true }; var response = (RetrieveMultipleResponse)mService.Execute(request); return response.BusinessEntityCollection; } |
For example, if we have a Loan custom entity and we want to return sets of borrowers (contacts):
1 2 3 4 5 6 | CrmServiceWrapper wrapper = new CrmServiceWrapper(crmOrganizationName, crmServer, crmPort, crmUsername, crmUserPassword, crmUserDomain); BusinessEntityCollection collection = wrapper.RetrieveEntityCollectionFromManyToMany( "new_loan_borrower" , "new_loan" , "new_loanid" , "new_name" , "2508280" , "contact" , "contactid" , null ); return collection.BusinessEntities; |
---
Second way is to use Fetch function to return the XML of the related entities:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | CrmServiceWrapper wrapper = new CrmServiceWrapper(crmOrganizationName, crmServer, crmPort, crmUsername, crmUserPassword, crmUserDomain); string linkFetch = @"<fetch mapping='logical'> <entity name='new_loan'> <filter type='and'> <condition attribute='new_name' operator='eq' value='2508280'/> </filter> <link-entity name='new_loan_borrower' from='new_loanid' to='new_loanid'> <attribute name='contactid'/> <link-entity name='contact' to='contactid'> <attribute name='new_armcontactid'/> <attribute name='fullname'/> </link-entity> </link-entity> </entity> </fetch>" ; string result = wrapper.FetchXML(linkFetch); XmlDocument doc = new XmlDocument(); doc.LoadXml(result); |
James Downey created a nice little program FetchXMLBuilder to help you build the fetch query.
---
Just for completion, below is the CRMServiceWrapper constructor that I use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | public CrmServiceWrapper( string organizationName, string serverName, string portNumber) { // Create authentication token for CrmService web service CrmAuthenticationToken token = new CrmAuthenticationToken(); token.AuthenticationType = 0; token.OrganizationName = organizationName; mService = new CrmService(); mService.Credentials = CredentialCache.DefaultCredentials; mService.CrmAuthenticationTokenValue = token; mService.Timeout = 300 * 1000; } public CrmServiceWrapper( string organizationName, string serverName, string portNumber, string username, string password, string domain) { NetworkCredential credential = new NetworkCredential(username, password, domain); RetrieveCrmTicketResponse ticketResponse = RetrieveCrmTicket(organizationName, serverName, portNumber, username, password, domain); // Create authentication token for CrmService web service CrmAuthenticationToken token = new CrmAuthenticationToken(); token.AuthenticationType = 0; token.OrganizationName = organizationName; token.CrmTicket = ticketResponse.CrmTicket; mService = new CrmService(); mService.Credentials = credential; mService.CrmAuthenticationTokenValue = token; mService.Timeout = 300 * 1000; } private RetrieveCrmTicketResponse RetrieveCrmTicket( string organizationName, string serverName, string portNumber, string username, string password, string domain) { NetworkCredential credential = new NetworkCredential(username, password, domain); // Configure CrmDiscoveryService Web service proxy dService = new CrmDiscoveryService(); dService.Url = "http://" + serverName + ":" + portNumber + "/mscrmservices/2007/AD/CrmDiscoveryService.asmx" ; dService.Credentials = credential; // Retrieve a list of available organisation RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest(); orgRequest.UserId = domain + "\\" + username; orgRequest.Password = password; RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)dService.Execute(orgRequest); // Find the target organization OrganizationDetail orgInfo = null ; foreach (OrganizationDetail orgDetail in orgResponse.OrganizationDetails) { if (orgDetail.OrganizationName.Equals(organizationName)) { orgInfo = orgDetail; break ; } } // Check if the organization was not found if (orgInfo == null ) throw new Exception( "The specified organization was not found." ); // Retrieve a CrmTicket from the CrmDiscoveryService web service RetrieveCrmTicketRequest ticketRequest = new RetrieveCrmTicketRequest(); ticketRequest.OrganizationName = organizationName; ticketRequest.UserId = domain + @"\" + username; ticketRequest.Password = password; RetrieveCrmTicketResponse ticketResponse = (RetrieveCrmTicketResponse)dService.Execute(ticketRequest); return ticketResponse; } |
Hope this helps ^_^
hy Andreas,
ReplyDeletei'm trying to insert a record in entity with many to many relationship. how do i do that??
i'm using crmservice.create method.
any ideas??
thanks
Hi, you should use AssociateRequest to establish the relationship. Example is in this blog:
Deletehttp://chaitanyaprasadtk.blogspot.com.au/2012/01/dealing-with-nn-relationship-in-crm.html
Thank you !! :)
ReplyDelete