Answered by:
CRM 2011 - Plugins Code (need help) loop through child record

Question
-
Hello Experts/Gurus,
Today is my first official attempt at Plugins and as expected i am struggling and really need you guys to help me through.
Here is my scenario:
I have two parent and child tables 1) Contact 2) Contact Address
- A contact can specify multiple addresses (for example Contact: Alex has three addresses or three records: A, B, C)
- On Contact Address table i have a boolean field "Primary Address", and as per business rule only address can be primary
- Requirement is as soon as i click PrimaryAddress = Yes for Address B, system has to make sure the flag (Primary Address) is set false on all the other records and this one would be yes. So in other words i have to loop through all the Addresses for the Contact. set the flag = NO, and then set the new value.
- And i think the plugin will be binded to "Contact Address" entity
Sorry to tell you but i don't know how to loop through all the contact address records :( here is my code (i have used SDK code as sample to get started):
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));Entity targetEntity = null;
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
targetEntity = (Entity)context.InputParameters["Target"];
if (targetEntity.LogicalName != "test_contactaddress")
{ return; }
}
else { return; }
try
{
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
// field: test_contactaddressesid is basically contact id that will get me list of all the addreses
Entity member = service.Retrieve("test_contactaddress", ((EntityReference)targetEntity["test_contactaddressesid"]).Id, new ColumnSet(true));
WHAT I WANT TO DO NEXT IS LOOP THROUGH THE CONTACT ADDRESS, SET THE FLAG 'PRIMARY ADDRESS' = NO, AND I DON'T KNOW HOW TO DO IT, i have checked the properties for member and can find any LENGTH or anything like that so i can setup the loop (hope i am explaining it correctly)
After the above loop part is done (hopefully you guys will point me right direction), i will do the following:
targetEntity.Attributes.Add("new_isprimaryaddress", true);
PLEASE GUIDE ME IN RIGHT DIRECTION, is there any resource only where i can get sample codes.
Look forward to hear from you.
Thank in advance.
Thursday, July 14, 2011 7:43 AM
Answers
-
GetAllChild is a kind of sample function that you can implement to fetch all child records, you can pass parent entity ID and service object.
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
Mahain : My Dynamics CRM Blog- Marked as answer by Jim Glass Jr Thursday, July 14, 2011 5:47 PM
Thursday, July 14, 2011 9:30 AMModerator -
you can take this post as a reference, it's for crm 4.0 but you can use the same way for ms crm 2011
Mahain : My Dynamics CRM Blog- Proposed as answer by HIMBAPModerator Thursday, July 14, 2011 2:56 PM
- Marked as answer by Jim Glass Jr Thursday, July 14, 2011 5:48 PM
Thursday, July 14, 2011 2:56 PMModerator
All replies
-
Hi,
On the contact address entity first you need to get parent entity ID (to search all childs), after getting all child entity records you need to loop through that resultset and need to check if it's ID (child entity) is not the same as with the current, if it's not the same means you need to update that record and need to set "Primary Address" fild to false.
> you need to use retrievemultiple request to fetch all child records based on Parent entity ID.
>you need to write this plugin on create/update, also you need to handle infinite loop as well because you will be writing update request in update plugin.
once you will all child record you can loop like below
DataCollection<Entity> Results= GetAllChild(ID,Service);
if (Results.Count > 0)
{
for (int index = 0; index < Result.Count;index++ )
{//create entity object and set property for "Primary Address" and update
}
}Let us know if you need any other information.
Mahain : My Dynamics CRM Blog- Proposed as answer by HIMBAPModerator Thursday, July 14, 2011 2:56 PM
Thursday, July 14, 2011 8:38 AMModerator -
Thanks Mahender, i am exactly following the logic here, but i apologize, need some help with the code.
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
I can't find GetAllChild function, also don't know what to pass as the ID, for the service parameter i think it should be created service object.
Would you be able to illustrate this with my code created in the above post?
Thursday, July 14, 2011 8:54 AM -
GetAllChild is a kind of sample function that you can implement to fetch all child records, you can pass parent entity ID and service object.
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
Mahain : My Dynamics CRM Blog- Marked as answer by Jim Glass Jr Thursday, July 14, 2011 5:47 PM
Thursday, July 14, 2011 9:30 AMModerator -
Hey Mahender, appreciate you response.
I know the logic exactly and how to get around with this, i was hoping to find a code snippet for this kind of process not a pseudo-code.
Thursday, July 14, 2011 11:54 AM -
you can take this post as a reference, it's for crm 4.0 but you can use the same way for ms crm 2011
Mahain : My Dynamics CRM Blog- Proposed as answer by HIMBAPModerator Thursday, July 14, 2011 2:56 PM
- Marked as answer by Jim Glass Jr Thursday, July 14, 2011 5:48 PM
Thursday, July 14, 2011 2:56 PMModerator -
Hi,
Try this code that I wrote for you:
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.Text; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; namespace CRMDemo.Plugins { public class UpdateContactAddresses : IPlugin { public void Execute(IServiceProvider serviceProvider) { IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); if (context.Depth > 1) { return; } // If you require tracing, uncomment the following line ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); Entity entity = null; // Check if the InputParameters property bag contains a target // of the current operation and that target is of type Entity. if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { // Obtain the target entity from the input parmameters. entity = (Entity)context.InputParameters["Target"]; // Test for an entity type and message supported by this plug-in. if (context.MessageName != "Create" && context.MessageName != "Update") { return; } if (context.PrimaryEntityName != "test_contactaddress") { return; } } else { return; } try { IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); if ((bool)entity["test_primaryaddress"] == true) { ConditionExpression ceAddress = new ConditionExpression("test_contactid", ConditionOperator.Equal, entity["test_contactid"]); ConditionExpression ceAddress2 = new ConditionExpression("test_contactaddressid", ConditionOperator.NotEqual, entity["id"]); QueryExpression qeAddresses = new QueryExpression("test_contactaddress"); qeAddresses.ColumnSet = new ColumnSet(new string[] { "test_primaryaddress" }); qeAddresses.Criteria.AddCondition(ceAddress); qeAddresses.Criteria.AddCondition(ceAddress2); EntityCollection results = service.RetrieveMultiple(qeAddresses); if (results.Entities.Count > 0) { foreach (var res in results.Entities) { res["test_primaryaddress"] = false; service.Update(res); } } } } catch (FaultException<OrganizationServiceFault> ex) { trace.Trace("Exception: " + ex.Message + " " + ex.StackTrace); throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex); } catch (Exception ex) { trace.Trace("Exception: " + ex.Message + " " + ex.StackTrace); throw new InvalidPluginExecutionException("An error occurred in the plug-in.", ex); } } } }
Hope this helps.
Kind regards,
Steve
- Proposed as answer by SteveGreen Saturday, November 30, 2013 1:25 PM
- Edited by SteveGreen Saturday, November 30, 2013 1:30 PM Added context.depth check
Saturday, November 30, 2013 1:25 PM