简体   繁体   English

删除消息插件不触发 Dynamics CRM

[英]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.我正在创建一个插件来计算每个父实体的子实体数量, noOfProduct在父实体的noOfProduct字段中显示数量。 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.所以每次当我创建一个新的子实体时, noOfProduct中 number 的值都会增加到 1。但是当我删除子实体时,我的插件没有触发,因此值保持不变。

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 . step: create您应该在delete注册。
  2. Pretty sure post-image is not supported on delete.可以肯定的,删除后不支持后期图像。 You need to use pre's.你需要使用pre。 "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 .您忘记调用方法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 :queryOppProdOnDel缺少这一行:

opportunity["new_noofproducts"] = noOfProduct;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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