locked
CRM 2011 Plugin: Set Option Set Value RRS feed

  • Question

  • hi,

    I have a requirement to set the optionset value of a child entity based on the optionset value of a parent entity (Both optionsets has different values). Since I'm very new to writing plugins, can someone help me. Any similar sample code will also help!

    Thx,

    Matt

    Monday, July 13, 2015 1:08 PM

Answers

  • Paul, aren't you posting something else here? It's a normal optionset, not a state change.

    I'm not used to work with LINQ so I'd write it like

    foreach(Entity ent in result.Entities)
    {
       OptionsetValue os = new OptionsetValue(<VALUE>);
       Entity upd = new Entity(ent.LogicalName);
       upd.Id = ent.Id;
       upd.Attributes.Add("myoptionset", os);
       service.Update(upd);
    }

    The casing might be off here but the general idea is there. The reason why I do a new update entity is that I've had crap happen when I update a fetched entity for some reason. Habit.

    BTW MAtt, if you register that plugin as a pre-state plugin you don't have to do the service.update

    Regards


    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 11:02 AM
    • Unmarked as answer by II2712a1 Wednesday, July 15, 2015 11:15 AM
    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:50 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 9:16 AM
  • First you need to retrieve the related records:

    QueryExpression qe = new QueryExpression("<childEntityName>");
    qe.Criteria.AddCondition("<parentLookupField>", ConditionOperator.Equal, parentId);
    
    EntityCollection results = _service.RetrieveMultiple(qe);
    

    Then you need to update the status of each, based on your status values:

    results.Entities.ToList().ForEach(a =>
    {
        _service.Execute(new SetStateRequest
        {
            EntityMoniker = a.ToEntityReference(),
            State = new OptionSetValue(state),
            Status = new OptionSetValue(status),
        });
    });

    Hope that helps

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 11:06 AM
    • Unmarked as answer by II2712a1 Wednesday, July 15, 2015 11:14 AM
    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:51 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 8:19 AM
  • I'd put the combination of the code Paul put together with the one I posted in the check where you set the optionset on the updated object.

    If the code is run in pre-operation, you don't need to do the service.update since the platform will do it for you.

    Regards


    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 11:34 AM
  • Yep my bad I read status somewhere!

    You can certainly modify both the snippets we provided to get what you're after.

    Something like this:

    QueryExpression qe = new QueryExpression("new_purchaseitem");
    qe.Criteria.AddCondition("new_itemnames", ConditionOperator.Equal, context.PrimaryEntityId);
    
    EntityCollection results = _service.RetrieveMultiple(qe);
    results.Entities.ToList().ForEach(a =>
    {
        Entity update = new Entity("new_purchaseitem");
        update.Id = a.Id;
        update["new_sapprstatus"] = new OptionSetValue(2); // Insert the value here
        service.Update(update);
    });

    Hope that helps

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:50 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 11:50 AM

All replies

  • hi,

    I have a requirement to set the optionset value of a child entity based on the optionset value of a parent entity (Both optionsets has different values). Since I'm very new to writing plugins, can someone help me. Any similar sample code will also help!

    Thx,

    Matt

    Anyone, any pointers?

    Thanks!

    Tuesday, July 14, 2015 8:07 AM
  • post the plugin code you already wrote 

    My blog: www.crmanswers.net - CRM Theme Generator

    Tuesday, July 14, 2015 8:29 AM
  • Hi Guido, Thanks for the response.

    What I do not know to achieve is: how to update the optionset value on a child entity (based on value from parent)

    My code - This is the working code for updating the same entity option set values

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Query;
    using Microsoft.Xrm.Sdk.Messages;
    using Microsoft.Crm.Sdk.Messages;
    
    namespace PIUpdate
    {
        public class UpdatePIStatus : IPlugin
        {
            public void Execute(IServiceProvider serviceProvider)
            {
                try
                {
                    ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
                    if (tracingService == null)
                    {
                        throw new InvalidPluginExecutionException(EntityMessages.TracingFailedMessage);
                    }
                    // Obtain the execution context from the service provider.           
                    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                    if (context.InputParameters.Contains(EntityMessages.TargetMessage))
                    {
                        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                        tracingService.Trace(EntityMessages.CreationMessageServiceObjectMessage, DateTime.Now.ToString());
                        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                        if (context.MessageName == EntityMessages.UpdateMessageName)
                        {
    
                            if (context.Depth > 1)
                            {
                                return;
                            }
    
                            // Obtain the target entity from the input parmameters.
                            Entity targetEntity = (Entity)context.InputParameters[EntityMessages.TargetMessage];
                            if (targetEntity == null)
                            {
                                return;
                            }
                            tracingService.Trace(EntityMessages.TargetEntityContextMessage, DateTime.Now.ToString());
                            if (targetEntity.LogicalName == PurchaseRequestEntityMessage.LogicalName)
                            {
                                Entity purchaseRequestEntity = null;
                                //EntityReference purchaseItemEntityRef = null;
                                if (context.InputParameters.Contains(EntityMessages.TargetMessage) && context.InputParameters[EntityMessages.TargetMessage] is Entity)
                                {
    
                                    purchaseRequestEntity = (Entity)context.InputParameters[EntityMessages.TargetMessage];
                                    if (purchaseRequestEntity.Attributes.Contains(PurchaseRequestEntityMessage.SAPPRAdminDecision) && ((OptionSetValue)purchaseRequestEntity.Attributes[PurchaseRequestEntityMessage.SAPPRAdminDecision]).Value == 1)
                                    {                                   
                                                OptionSetValue myoptionset = new OptionSetValue();
                                                myoptionset.Value = 2;
                                                purchaseRequestEntity.Attributes["new_sapprstatus"] = myoptionset;
                                                if (purchaseRequestEntity != null)
                                                {
                                                    service.Update(purchaseRequestEntity);
                                                }
                                                    
                                              
                                    }
                            
    
    
                                }
    
    
    
                            }
                        }
                    }
    
                }
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException(ex.Message + " " + ex.StackTrace, ex);
                }
    
            }
        }
    }
    

    What I actually need is: to update the referential child entity option set values.

    Thanks for your help in advance!

    Tuesday, July 14, 2015 9:52 AM
  • Any ideas on how to do the same?
    Tuesday, July 14, 2015 1:28 PM
  • First you need to retrieve the related records:

    QueryExpression qe = new QueryExpression("<childEntityName>");
    qe.Criteria.AddCondition("<parentLookupField>", ConditionOperator.Equal, parentId);
    
    EntityCollection results = _service.RetrieveMultiple(qe);
    

    Then you need to update the status of each, based on your status values:

    results.Entities.ToList().ForEach(a =>
    {
        _service.Execute(new SetStateRequest
        {
            EntityMoniker = a.ToEntityReference(),
            State = new OptionSetValue(state),
            Status = new OptionSetValue(status),
        });
    });

    Hope that helps

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 11:06 AM
    • Unmarked as answer by II2712a1 Wednesday, July 15, 2015 11:14 AM
    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:51 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 8:19 AM
  • Paul, aren't you posting something else here? It's a normal optionset, not a state change.

    I'm not used to work with LINQ so I'd write it like

    foreach(Entity ent in result.Entities)
    {
       OptionsetValue os = new OptionsetValue(<VALUE>);
       Entity upd = new Entity(ent.LogicalName);
       upd.Id = ent.Id;
       upd.Attributes.Add("myoptionset", os);
       service.Update(upd);
    }

    The casing might be off here but the general idea is there. The reason why I do a new update entity is that I've had crap happen when I update a fetched entity for some reason. Habit.

    BTW MAtt, if you register that plugin as a pre-state plugin you don't have to do the service.update

    Regards


    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 11:02 AM
    • Unmarked as answer by II2712a1 Wednesday, July 15, 2015 11:15 AM
    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:50 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 9:16 AM
  • Thanks Paul and Richard. Much appreciated for taking time to help!

    Maybe a little more extended guidance from you, where would i append the piece of code you gave. I guess, right after checking the option set condition? I'm a little confused here as how to go about updating this logic with which the logic i already have ( please see above)

    My child entity name is: new_purchaseitem

    Lookup fieldname from parent entity is: new_itemnames

    Optionset field schemaname to be updated is: new_sapprstatus

    Appreciate your patience and help!

    Thanks!

    Wednesday, July 15, 2015 11:28 AM
  • Also Im doing this is the "pre-operation" event.
    Wednesday, July 15, 2015 11:29 AM
  • I'd put the combination of the code Paul put together with the one I posted in the check where you set the optionset on the updated object.

    If the code is run in pre-operation, you don't need to do the service.update since the platform will do it for you.

    Regards


    Rickard Norström Developer CRM-Konsulterna
    http://www.crmkonsulterna.se
    Swedish Dynamics CRM Forum: http://www.crmforum.se
    My Blog: http://rickardnorstrom.blogspot.se

    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 11:34 AM
  • Yep my bad I read status somewhere!

    You can certainly modify both the snippets we provided to get what you're after.

    Something like this:

    QueryExpression qe = new QueryExpression("new_purchaseitem");
    qe.Criteria.AddCondition("new_itemnames", ConditionOperator.Equal, context.PrimaryEntityId);
    
    EntityCollection results = _service.RetrieveMultiple(qe);
    results.Entities.ToList().ForEach(a =>
    {
        Entity update = new Entity("new_purchaseitem");
        update.Id = a.Id;
        update["new_sapprstatus"] = new OptionSetValue(2); // Insert the value here
        service.Update(update);
    });

    Hope that helps

    Paul


    If my response helped you find your answer please show your thanks by taking the time to "Mark As Answer" and "Vote As Helpful".

    Twitter LinkedIn Facebook Blog Magnetism

    • Proposed as answer by Paul Nieuwelaar Wednesday, July 15, 2015 11:50 AM
    • Marked as answer by II2712a1 Wednesday, July 15, 2015 4:30 PM
    Wednesday, July 15, 2015 11:50 AM
  • Thank you both. I will try that.
    Wednesday, July 15, 2015 4:31 PM