locked
delete CRM plug-in issue RRS feed

  • Question

  • My delete plug-in fires on pre-delete operation of Invoice Detail.  {CRM 2011 online}

    Plugin is registered on Invoice Detail entity;   Fires on Pre-delete operation;

    new_customentity  and have  fields to capture invoice and invoice detail info–

    “new_invoiceid” <lookup to invoice entity>

    “new_invoicedetailid”  <this is a text field, where I store the invoicedetail GUID>

    When I create an invoice line item, I create a custom entity records and capture the invoicedetailid in the “new_invoicedetailid” field.   I have created a plug-in and it works fine.  However, the delete plug-in doesn’t seem to fire.  Below is the code. Appreciate if someone advise what am I missing here. 

    Entity invoicedetailincontext = (Entity)context.InputParameters["Target"];
    
              
              Entity customentity = new Entity("new_customeentity");
              QueryExpression qry = new QueryExpression("new_customeentity");
              barqry.ColumnSet = new ColumnSet(new string[]{ 
    			“new_customentityid” 
              "new_invoiceid",
              "new_detailid,
              "new_description"
              });
              qry.Criteria = new FilterExpression();
              qry.Criteria.AddCondition(new ConditionExpression("new_detailid", ConditionOperator.Equal, invoicedetailincontext.Id.ToString()));
    
              // Pass query to service proxy 
              EntityCollection col = service.RetrieveMultiple(qry);
    
              if (col.Entities.Count > 0)
              {
                foreach (var myentity in col.Entities)
                {
                  service.Delete(customentity.LogicalName, myentity.Id);
                }
              }
    
    


     

    Wednesday, August 10, 2011 8:25 PM

Answers

  • Hi,

    In plugin delete step, Entity object will not be passed into the context Target paramter but EntityReference will be passed so try change code first line to:

     

    EntityReference invoicedetailincontext = (EntityReference)context.InputParameters["Target"];
    

    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    • Marked as answer by CRM elite Wednesday, August 10, 2011 9:41 PM
    Wednesday, August 10, 2011 8:37 PM
  • Hi,

    Update message plugin context entity paramter will only contains attributes that has been updated, it will not contain a list of all attributes. If you want to retrieve all attributes then you can register Update message for Post-Operation and can call CrmService.Retrieve(entityname, entityid, ..) to retrieve entity all attributes.


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    • Proposed as answer by Jehanzeb.Javeed Thursday, August 11, 2011 12:02 AM
    • Marked as answer by CRM elite Thursday, August 11, 2011 12:48 AM
    Wednesday, August 10, 2011 11:28 PM

All replies

  • Hi,

    In plugin delete step, Entity object will not be passed into the context Target paramter but EntityReference will be passed so try change code first line to:

     

    EntityReference invoicedetailincontext = (EntityReference)context.InputParameters["Target"];
    

    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    • Marked as answer by CRM elite Wednesday, August 10, 2011 9:41 PM
    Wednesday, August 10, 2011 8:37 PM
  • Thanks javeed. In fact, the plug-in validate for the entity before. does that mean, i need to modify this portion as well. <this is the beginning of the plug-in> 

     

     if (context.InputParameters.Contains("Target") &&
        context.InputParameters["Target"] is Entity)
       {
        // Obtain the target entity from the input parmameters.
        Entity entity = (Entity)context.InputParameters["Target"];
        //</snippetFollowupPlugin2>
    
        // Obtain the organization service reference.
        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
    
    
        // Verify that the target entity
        // If not, this plug-in was not registered correctly.
        if (entity.LogicalName != "invoicedetail")
         return;
    


     


    Wednesday, August 10, 2011 9:09 PM
  • I am assuming I need to change - if (context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is EntityReference)
    EntityReference entityref = (EntityReference)context.InputParameters["Target"];
      
                    if (entityref.LogicalName!= "invoicedetail")
                        return;

    Wednesday, August 10, 2011 9:15 PM
  • On DeleteRequest Target parameter contains only entity reference and not entity.

    Also, It is better to create cascading relationship between invoicedetail and customentity and configure to delete all child custom entity records on deletion of parent invoicedetail., so you dont need a plugin.


    Faizal Khan
    Wednesday, August 10, 2011 9:16 PM
  • We can't set the 1:N relationship from invoicedetail to customentity. 
    Wednesday, August 10, 2011 9:22 PM
  • Hi,

    yes cascade delete all in Relationship Delete is better than using a plugin on delete message for deleting child record.


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".

    Wednesday, August 10, 2011 9:28 PM
  • I am assuming I need to change - if (context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is EntityReference)
    EntityReference entityref = (EntityReference)context.InputParameters["Target"];
      
                    if (entityref.LogicalName!= "invoicedetail")
                        return;


    This is correct code..
    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    Wednesday, August 10, 2011 9:35 PM
  • Hi, how could I set the casecade delete all? Please suggest. 
    Wednesday, August 10, 2011 9:43 PM
  • could you please suggest how could I set this? Do I need to create 1 to many or N:1  from customentity to invoicedetail? because invoicedetail doesn't allow 1:N or N:1 to custom entity 
    Wednesday, August 10, 2011 9:45 PM
  • Hi,

    You are right we can not configure this reltionship for the invoicedetails entity, for relationship cascading we require 1:N relationship. for InvoiceDetail entity you have to use plugin code as we can not create 1:N relationship.


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    Wednesday, August 10, 2011 9:48 PM
  • With the update plug-in, I have  a conflict between create and update plug-in; I noticed that the upgrade plug-in also triggered for create action! that threw business process error!

    Q1) how could I prevent it?  

    Q2) Is there a way for me to pass the guid of the newly created record (in pre-operation of Create) to post-operation of "Create". that way I can actually store the guid of the newly created record in invoicedetail itself; I could do only in post-operation.

     

    Wednesday, August 10, 2011 9:55 PM
  • Hi,

    1) Update plugin should not trigger for Create unless you are updating the entity record? are you updating record in post-operation? if updating then it will trigger update message.

    2) Yes you can pass the GUID of newly created id from Pre-Operation to Post-Operation using plugin shared variables. You may reffer SDK example: http://msdn.microsoft.com/en-us/library/gg328579.aspx


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".

    Wednesday, August 10, 2011 10:02 PM
  • upload plugin doesn't seem to fire. Does this also works on EntityReference? 
    Wednesday, August 10, 2011 10:59 PM
  • Hi,

    Make sure that you have registered on Update entity message for SYnchronous execution. Update work with Entity, sample code:

     if (context.InputParameters.Contains("Target") &&
    

                        context.InputParameters["Target"] is Entity)
                    {
                        // Obtain the target entity from the input parmameters.
                        Entity entity = (Entity)context.InputParameters["Target"];

                        // Obtain the organization service reference.
                        switch (context.MessageName)
                        {
                            case "Update":
                                // Verify that the target entity represents an account.
                                // If not, this plug-in was not registered correctly.
                                if (entity.LogicalName == "my_entity_name")
                                {

                                 }

                        }

    }


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    • Proposed as answer by Jehanzeb.Javeed Wednesday, August 10, 2011 11:02 PM
    Wednesday, August 10, 2011 11:02 PM
  • I am getting errors like given key not present. I pretty much use the same code that use to delete as above (except service.update). I used the entity but not entityreference. Does update operation also uses EntityReference?

     

    please advise

     

    Wednesday, August 10, 2011 11:21 PM
  • Hi,

    Update message plugin context entity paramter will only contains attributes that has been updated, it will not contain a list of all attributes. If you want to retrieve all attributes then you can register Update message for Post-Operation and can call CrmService.Retrieve(entityname, entityid, ..) to retrieve entity all attributes.


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    • Proposed as answer by Jehanzeb.Javeed Thursday, August 11, 2011 12:02 AM
    • Marked as answer by CRM elite Thursday, August 11, 2011 12:48 AM
    Wednesday, August 10, 2011 11:28 PM
  • Thanks Javeed. Thats what I did before (post operation and use the Retrieve method). but now I know why. 
    Wednesday, August 10, 2011 11:58 PM
  • Hi, I have many related (child) records for each customentity< i.e. invoicedetail>. Each child record will have text fields & lookup say (a, b, c). I need to find an efficient way to combine and keep the most current set or even array of records after every create, update or delete action.  for every invoicedetail <customentity>there could be 10s of child (some may have upto 400s) and I finally need to capture this combined string in invoice-detail entity. The combined text should be 

    a1+b1+c1 <next line> 

    a2+b2+c2 <next line> ...

    an+bn+cn 

    Appreciate your thoughts. 

     

    Thursday, August 11, 2011 1:01 AM
  • Hi Javeed, any thoughts on thi

    I have many related (child) records for each customentity< i.e. invoicedetail>. Each child record will have text fields & lookup say (a, b, c). I need to find an efficient way to combine and keep the most current set or even array of records after every create, update or delete action.  for every invoicedetail <customentity>there could be 10s of child (some may have upto 400s) and I finally need to capture this combined string in invoice-detail entity. The combined text should be 

    a1+b1+c1 <next line> 

    a2+b2+c2 <next line> ...

    an+bn+cn 

    I am thinking of either to use a custom ribbon element which will call the plug-in to process this aschyn mode. is it feasible. or any other suggestions. please advise.

    Thursday, August 11, 2011 1:50 PM
  • Hi,


    You cannot use ribbon element to call plugin unless you update data into form and save for submission and if plugin is registered for Update event then it will only work and this approach will not work on child entity record creation and deletion.

    If you are looking for real-time solution then register plugin steps as below.
    I would suggest you the following:

    1. Write a method that will combine all entities text as per required by fetching all child entity records (Retrieve Multiple or LinQ will do the job)
    2. Register plugin steps for:
      a. Create Message on Post-Operation Asynchronous Execution (System will create a System Job for execution will take time like workflow execution)
      b. Update Message on Post-Operation Asynchronous Execution
      c. Delete Message on Pre-Operation, you cannot do it on Post-Operation because record will be deleted and you will be unable to retrieve parent entity Id. Recommend is to use Pre Operation Synchronous Execution


    Jehanzeb Javeed

    http://worldofdynamics.blogspot.com
    Linked-In Profile |CodePlex Profile

    If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".
    Thursday, August 11, 2011 4:09 PM