简体   繁体   中英

Delete message plug-in not firing Dynamics CRM

I have a parent entity and child entity. I'm creating a plugin to count number of child entities for each parent entity and display the number in noOfProduct field in parent entity. So every time when I created a new child entity, the value of number in noOfProduct will be increment to 1. But when I deleted the child entity, my plugin is not triggering, hence the value remain the same.

I registered my plugin,

step: create
primary entity: child_entity
event_pipeline: post-operation
synchronous 
Plugin Images: post-image

This is my complete code.

using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Client;
using System.Net;
using System.Web.Services;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NoOfProductsPlugin
{
  public class NoOfProducts : IPlugin
  {
    public void Execute(IServiceProvider serviceProvider)
    {
        ITracingService tracingService = 

   (ITracingService)serviceProvider.GetService(typeof(ITracingService));
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        //for create and update event
        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            // Obtain the target entity from the input parmameters.
            Entity targetEntity = (Entity)context.InputParameters["Target"];

            // Verify that the entity represents a connection.
            if (targetEntity.LogicalName != "child_entity")
            {
                return;
            }
            else
            {
                try
                {
                    //triggered upon create or update message
                    if (context.MessageName == "Create" || context.MessageName == "Update")
                    {
                        Entity postMessageImage;
                        Guid oppId = new Guid();

                        if (context.PostEntityImages.Contains("postMessageImage") && context.PostEntityImages["postMessageImage"] is Entity)
                        {
                            postMessageImage = (Entity)context.PostEntityImages["postMessageImage"];
                            oppId = ((EntityReference)postMessageImage.Attributes["lookup_fieldtoParent"]).Id;
                        }

                        //throw new InvalidPluginExecutionException

                        queryOppProd(service, oppId);
                    }

                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred :-" + ex.Message, ex);
                }
                //</snippetFollowupPlugin3>

                catch (Exception ex)
                {
                    tracingService.Trace("An error occurred  : {0}" + ex.Message, ex.ToString());
                    throw;
                }
            }
        }
        //for delete event use entityreference
        else if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
        {
            // Obtain the target entity from the input parmameters.
            EntityReference targetEntity = (EntityReference)context.InputParameters["Target"];

            // Verify that the entity represents a connection.
            if (targetEntity.LogicalName != "child_entity")
            {
                return;
            }
            else
            {

                try
                {
                    //triggered upon delete message
                    if (context.MessageName == "Delete")
                    {
                        Guid oppProdId = targetEntity.Id;

                        // retrieve oppid guid
                        Entity oppProd = new Entity("child_entity");
                        ColumnSet columns_ = new ColumnSet(new string[] { "lookup_fieldtoParent" });
                         oppProd = service.Retrieve(oppProd.LogicalName, oppProdId, columns_);

                        Guid oppId = new Guid();
                        oppId = ((EntityReference)oppProd["lookup_fieldtoParent"]).Id;

                        //throw new InvalidPluginExecutionException(
                    }

                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred :-" + ex.Message, ex);
                }
                //</snippetFollowupPlugin3>

                catch (Exception ex)
                {
                    tracingService.Trace("An error occurred: {0}" + ex.Message, ex.ToString());
                    throw;
                }
            }
        }
    }
    public void queryOppProd(IOrganizationService service, Guid oppId)
    {
        int noOfProduct = 0;

        QueryExpression oppProdQuery = new QueryExpression { EntityName = "child_entity", ColumnSet = new ColumnSet("child_entityid", "lookup_fieldtoParent") };
        oppProdQuery.Criteria.AddCondition("lookup_fieldtoParent", ConditionOperator.Equal, oppId); // to search for child_entity that linked to the selected parent_entity
        EntityCollection oppProdQueryRetrieve = service.RetrieveMultiple(oppProdQuery);

        if (oppProdQueryRetrieve != null && oppProdQueryRetrieve.Entities.Count > 0)
        {
            for (var i = 0; i < oppProdQueryRetrieve.Entities.Count; i++)
            {

                noOfProduct++;
            }
        }

        //declare table used to retrieve the field and update
        Entity opportunity = new Entity("parent_entity");
        ColumnSet columns = new ColumnSet(new string[] { "new_noofproducts" });
        opportunity = service.Retrieve(opportunity.LogicalName, oppId, columns);

        opportunity["new_noofproducts"] = noOfProduct;
        service.Update(opportunity);
    }

    public void queryOppProdOnDel(IOrganizationService service, Guid oppId, Guid oppProdId)
    {
        int noOfProduct = 0;


        //query opportunityProduct by using opportunity guid
        QueryExpression oppProdQuery = new QueryExpression { EntityName = "child_entity", ColumnSet = new ColumnSet("child_entityid", "lookup_fieldtoParent") };

        FilterExpression oppProdQueryFilter = oppProdQuery.Criteria.AddFilter(LogicalOperator.And);
        oppProdQueryFilter.AddCondition("child_entityid", ConditionOperator.NotEqual, oppProdId);
        oppProdQueryFilter.AddCondition("lookup_fieldtoParent", ConditionOperator.Equal, oppId); // to search for child_entity that linked to the selected parent_entity
        EntityCollection oppProdQueryRetrieve = service.RetrieveMultiple(oppProdQuery);

        if (oppProdQueryRetrieve != null && oppProdQueryRetrieve.Entities.Count > 0)
        {
            for (var i = 0; i < oppProdQueryRetrieve.Entities.Count; i++)
            {

                noOfProduct++;
            }
        }
        //throw new InvalidPluginExecutionException

        //declare table used to retrieve the field and update
        Entity opportunity = new Entity("parent_entity");
        ColumnSet columns = new ColumnSet(new string[] { "new_noofproducts" });

        opportunity = service.Retrieve(opportunity.LogicalName, oppId, columns);
        service.Update(opportunity);
    }
}
}

Couple of points:

  1. step: create You should register on delete .
  2. Pretty sure post-image is not supported on delete. You need to use pre's. "The create operation doesn't support a pre-image and a delete operation doesn't support a post-image."

  3. Your basic design has a flaw. If lots of changes occur at the same time, they could all execute concurrently on seperate threads, this means the count could be incorrect in some circumstances.

You forgot to call the method queryOppProdOnDel .

When you register your Plugin assembly & Step on Delete message, replace the below snippet in your code.

                   //triggered upon delete message
                    if (context.MessageName == "Delete")
                    {
                        Guid oppProdId = targetEntity.Id;

                        // retrieve oppid guid
                        Entity oppProd = new Entity("child_entity");
                        ColumnSet columns_ = new ColumnSet(new string[] { "lookup_fieldtoParent" });
                         oppProd = service.Retrieve(oppProd.LogicalName, oppProdId, columns_);

                        Guid oppId = new Guid();
                        oppId = ((EntityReference)oppProd["lookup_fieldtoParent"]).Id;

                        //throw new InvalidPluginExecutionException(

                        queryOppProdOnDel(service, oppId, oppProdId);
                    }

Update:

This line is missing in queryOppProdOnDel :

opportunity["new_noofproducts"] = noOfProduct;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM