locked
Setting an entity reference in a plugin RRS feed

  • Question

  • I'm trying to set an entity reference from within a plugin. It's on the associate of two entities - stock and application form. When a stock item is associated with an application form, I get the name of the applicant (which is another entity - Contact) from a look up on the application form, and populate a look up on the stock item with that contact.

    Here is my code:

            private const string ASSOCIATE = "Associate";
            private const string DISASSOCIATE = "Disassociate";
    
            public void Execute(IServiceProvider serviceProvider)
            {
                try
                {
                  
                    PluginSetup(serviceProvider);
    
                    if (context.MessageName == ASSOCIATE || context.MessageName == DISASSOCIATE)
                    {
                        // Get the Relationship Key from context
                        if (context.InputParameters.Contains("Relationship"))
                        {
                            string relationshipName = context.InputParameters["Relationship"].ToString();
                          
                            // Check the Relationship Name with intended one
                           if (relationshipName == "applicationForm_stock")
                            {
                                if (context.MessageName == ASSOCIATE)
                                {
                                    SaveAssociatedStock(ASSOCIATE);
                                }
                                else if (context.MessageName == DISASSOCIATE)
                                {
                                    SaveAssociatedStock(DISASSOCIATE);
                                }
                            }
                            else
                            {
                                return;
                            }
                        }
                    }
    
                }
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred");
                }
            }
    
            private void SaveAssociatedStock(string messageType)
            {
                try
                {
                    EntityReference applicationFormEntity = null;
                    EntityReferenceCollection stockEntities = null;
                    EntityReference contactEntityReference = null;
                    Entity stockItem = new Entity();
    
                    ColumnSet nameCol = new ColumnSet();
                    nameCol.AddColumn("name");
                    
                    ColumnSet contactNameCol = new ColumnSet();
                    contactNameCol.AddColumn("contactname");
    
                    // Get Application Form entity reference from Target Key from context
                    if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
                    {
                        applicationFormEntity = (EntityReference)context.InputParameters["Target"];
                        Trace("applicationFormEntity.Id: " + applicationFormEntity.Id);
                        Entity test = service.Retrieve("applicationForm", applicationFormEntity.Id, contactNameCol);
    					// Get the contact name from the contact lookup on the application form
                        contactEntityReference = (EntityReference)test.Attributes["contactname"];                   
                    }
                                    
                    // Get Stock reference from RelatedEntities Key from context
                    if (context.InputParameters.Contains("RelatedEntities") && context.InputParameters["RelatedEntities"] is EntityReferenceCollection)
                    {
                        stockEntities = context.InputParameters["RelatedEntities"] as EntityReferenceCollection;
                       
                        for (int i = 0; i < stockEntities.Count; i++)
                        {
                            // Get name of current Stock item  
                            stockItem = service.Retrieve("stock", stockEntities[i].Id, nameCol);
    
                            if (messageType == ASSOCIATE)
                            {
                                // Add the contact to the current Stock item record
                                Entity updateStockItem = new Entity("stock");
                                updateStockItem.Attributes.Add(new KeyValuePair<string, object>("stockid", stockEntities[i].Id));
    
                                updateStockItem.Attributes.Add(new KeyValuePair<string, object>("owner", contactEntityReference.Id));
                                
                                service.Update(updateStockItem);
                            }
                            else if (messageType == DISASSOCIATE)
                            {
                                // Remove the contact from the current Stock item record
                                Entity updateStockItem = new Entity("stock");
                                updateStockItem.Attributes.Add(new KeyValuePair<string, object>("stockid", stockEntities[i].Id));
    
                                updateStockItem.Attributes.Add(new KeyValuePair<string, object>("owner", null));
                                
                                service.Update(updateStockItem);
                                
                            }
                        }
                   
                    }

    However, I'm getting this error:

     <Message>An error occurred in the AssociateEntities.AssociateEntities.Execute plug-in.An error occurred in the AssociateEntities.AssociateEntities.SaveAssociatedStock plug-in.System.InvalidCastException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #863F0E66</Message>

    All my IDs have valid values in them, as I've already put in trace logging, and can see that they are correct.

    Thanks.


    Wednesday, August 7, 2013 11:30 AM

All replies

  • Hi,
    as far as I know there are no such standard entities as applicationform or stock inside Dynamics CRM.

    Probably you are dealing with custom entities, in this case the name will be something like new_stock (or the solution prefix)

    Also the relationship and the fields name will contain the solution prefix. In addition the standard the owner field is always ownerid.


    My blog: www.crmanswers.net

    Wednesday, August 7, 2013 11:51 AM
  • Thanks, but I just renamed those entities and fields when posting the code up here. There's definitely no problem with them. They are custom entities and they have the solution prefix like you mentioned. As does the relationship name etc.
    Wednesday, August 7, 2013 11:54 AM
  • If you don't post your exact code someone (as me in this case) will always raise the doubt about its validity.

    However the only point where you can get an InvalidCastException is this line:

     contactEntityReference = (EntityReference)test.Attributes["contactname"];    

    because the other two cast (Target and RelatedEntities) are executed after a validity check.

    Probably the attribute "contactname" is empty (or is not a lookup at all)

    to check if is not empty you can use this code:

    if (test.Attributes.Contains("contactname") && test.Attributes["contactname"] != null) {
    // ... rest of your code
    }


    My blog: www.crmanswers.net

    Wednesday, August 7, 2013 12:04 PM
  • Thanks.

    Underneath that line, I have entered the following:

    Trace("contactEntityReference.Id: " + contactEntityReference.Id);

    and I get a valid ID
    Wednesday, August 7, 2013 12:07 PM
  • In this case add a trace after every line to discover which is the line that generate the exception.

    Another thing I noticed: in these lines you are setting a lookup:

    updateStockItem.Attributes.Add(new KeyValuePair<string, object>("stockid", stockEntities[i].Id));
    updateStockItem.Attributes.Add(new KeyValuePair<string, object>("owner", contactEntityReference.Id));

    you need to set the value to the entityreference, not the guid (or the value will not be filled) as:

    updateStockItem.Attributes.Add("stockid", new EntityReference("stock",stockEntities[i].Id));
    
    // or set directly with the entityReference
    
    updateStockItem.Attributes.Add("stockid", stockEntities[i]);
    


    My blog: www.crmanswers.net

    Wednesday, August 7, 2013 12:22 PM