Retrieving related records in CRM may not be straightforward for someone starting out in CRM development. I previously wrote about how you can do this using QueryExpression and LinkEntity. However, I recently learnt of another, and probably better, approach using RetrieveRequest. This post explains this approach.
Scenario
I have two entities: Course (logical name ng_course) and Subject (logical name ng_subject). These entities are in an N:N relationship (relationship name ng_course_subject). I need to retrieve all the related Subjects for a given Course.
Approach explained
You might be tempted to first retrieve the Course entity by its ID (using the IOrganizationService.Retrieve() method) and then access the RelatedEntities property of the returned object. This however will not work, as the RelatedEntities property will be empty for entities retrieved using this way.
The RelatedEntities property will be populated as expected if we use the IOrganizationService.Execute() method and passing in a correctly setup RetrieveRequest object. The code below demonstrates how this can be done. Review the comments.
//Credentials for invoking the service var credentials = new ClientCredentials(); credentials.UserName.UserName = "mydomain\\user1"; credentials.UserName.Password = "password1"; var organisationUrl = new Uri("http://nguyen5:5555/NguyenOrg/XRMServices/2011/Organization.svc"); var service = new OrganizationServiceProxy(organisationUrl, null, credentials, null); //This is the ID of the Course, i.e. the parent record of the related Subject records that we need to retrieve. var courseID = "7CF5E251-30C1-E311-84ED-00155DAB7703"; //Creating a new request var retrieveRequest = new RetrieveRequest(); //The way RetrieveRequest works is that we tell it to retrieve //a particular record, and also retrieve the related records for that //record at the same time. Therefore, the Target property of the request //will be set to the parent record. We will subsequently specify the //relationship for the request so that the right related //records will also be retrieved. retrieveRequest.Target = new EntityReference("ng_course", new Guid(courseID)); //The columns to retrieve for the parent record retrieveRequest.ColumnSet = new ColumnSet("ng_maximumcreditpoints", "ng_name"); //This is where we specify the relationship for the request to retrieve //the related records. Note that you can retrieve multiple types of related //records by adding multiple relationships here. retrieveRequest.RelatedEntitiesQuery = new RelationshipQueryCollection(); //The name of the relationship retrieveRequest.RelatedEntitiesQuery.Add(new Relationship("ng_course_subject"), //Name of the related entities new QueryExpression("ng_subject") { //The columns to retrieve for the related records ColumnSet = new ColumnSet("ng_creditpoints", "ng_name") //Note that you can further filter the related records to be returned by //specifying the Criteria property for the QueryExpression. }); //Execute the request and process the response var response = (RetrieveResponse)service.Execute(retrieveRequest); Console.WriteLine("Course name: {0}, Max credit points: {1}", response.Entity["ng_name"], response.Entity["ng_maximumcreditpoints"]); //The RelatedEntities property is now populated with the related records foreach (var relatedSubject in response.Entity.RelatedEntities[new Relationship("ng_course_subject")].Entities) { Console.WriteLine("Subject name: {0}, Credit points: {1}", relatedSubject["ng_name"], relatedSubject["ng_creditpoints"]); }
Very well explained! Thanks for this post. Made me more educated on CRM 🙂