[英]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:几点:
step: create
You should register on delete
. step: create
您应该在delete
注册。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." “创建操作不支持前映像,删除操作不支持后映像。”
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.