Dynamics CRM商机插件问题:预估结束时间变更后子网格未同步
问题诊断与修复方案
你的插件没生效主要是因为几个核心逻辑错误,我帮你拆解一下:
1. 触发条件判断完全错误
你代码里写的是if (entity.Contains("name"))——这意味着只有当商机的**名称(name字段)**变更时,才会执行后续的同步逻辑,但你的需求是当estimatedclosedate(预估结束时间)变更时触发!这直接导致你修改预估结束时间时,代码根本没进入到同步的分支里。
2. 查询对象与逻辑完全偏离需求
你用FetchXML查询的是opportunity实体,但你需要更新的是商机产品(opportunityproduct)!现在的查询逻辑完全不对:你查的是当前商机的contactid(这和商机产品毫无关系),然后还把查询到的商机实体ID当成商机产品的ID去更新,这肯定找不到对应的商机产品,自然不会有任何变化。
3. 次要问题:变量拼写错误
IOrganizationServiceFactory srevicefactory里的srevicefactory拼写错误(应该是servicefactory),虽然这个不一定导致运行错误,但属于代码规范问题,容易引发其他排查障碍。
修正后的代码
我帮你调整了逻辑,修复了以上问题,还加入了日志追踪方便排查:
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); // 验证目标实体是商机,且是更新操作 if(context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity opportunityEntity) { // 检查是否修改了预估结束时间(estimatedclosedate) if (opportunityEntity.Contains("estimatedclosedate")) { tracingService.Trace("开始同步商机产品的new_valid_to字段"); // 构造FetchXML查询当前商机下的所有商机产品 var fetchXml = $@" <fetch no-lock='true'> <entity name='opportunityproduct'> <attribute name='opportunityproductid'/> <filter> <condition attribute='opportunityid' operator='eq' value='{opportunityEntity.Id}'/> </filter> </entity> </fetch>"; try { var opportunityProducts = service.RetrieveMultiple(new FetchExpression(fetchXml)).Entities; tracingService.Trace($"找到{opportunityProducts.Count}个商机产品"); foreach (var product in opportunityProducts) { Entity productToUpdate = new Entity("opportunityproduct", product.Id); productToUpdate["new_valid_to"] = opportunityEntity["estimatedclosedate"]; service.Update(productToUpdate); tracingService.Trace($"已更新商机产品ID: {product.Id}的new_valid_to字段"); } } catch (Exception ex) { tracingService.Trace($"同步出错: {ex.Message}"); throw new InvalidPluginExecutionException("同步商机产品有效期失败: " + ex.Message); } } } }
插件注册的关键注意事项
除了代码修复,你还需要确保插件注册的配置正确,否则还是不会生效:
- 消息类型:选择
Update(更新)消息 - 主实体:选择
Opportunity(商机) - 筛选字段:一定要勾选
estimatedclosedate,这样只有当这个字段变更时才会触发插件,避免不必要的执行 - 执行阶段:建议选择
PostOperation(后操作),确保商机的预估结束时间已经成功保存后再同步产品字段 - 执行模式:选择
Synchronous(同步),这样用户操作后能立即看到产品字段的变化
内容的提问来源于stack exchange,提问作者Ahmed Mehany
相关产品推荐
相关产品推荐

