如何在MS CRM中通过插件实现记录所有者变更时自动更新分支与国家字段?
MS CRM 插件实现所有者变更同步分支/国家字段
前置确认
动手前先理清楚依赖关系:
- 自定义实体(比如
new_customentity)需包含:ownerid(系统默认所有者字段)、new_branch(分支字段)、new_country(国家字段) - 系统用户实体(
systemuser)需包含:new_portfolioowner(指向投资组合所有者的Lookup字段)、new_branch、new_country(存储投资组合所有者的分支/国家信息)
插件注册配置
- 触发消息:选择自定义实体的
Update消息 - 筛选条件:仅当
ownerid字段发生变更时触发插件(避免不必要的执行损耗) - 执行阶段:设置为
Post Operation(必须等所有者更新完成后,才能获取到最新的所有者信息) - 执行模式:同步模式(确保字段实时更新)
- 实体镜像:添加Post Entity Image,包含
ownerid字段,用于获取更新后的完整所有者数据
插件核心代码实现
用C#编写插件逻辑,核心步骤如下:
using Microsoft.Xrm.Sdk; using System; public class SyncBranchCountryOnOwnerChange : IPlugin { public void Execute(IServiceProvider serviceProvider) { // 获取插件上下文与服务实例 IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); try { // 仅处理Update消息,且目标实体存在 if (context.MessageName != "Update" || !context.InputParameters.Contains("Target")) return; Entity targetEntity = (Entity)context.InputParameters["Target"]; Entity postImage = context.PostEntityImages["PostImage"]; // 检查所有者是否发生变更 if (!targetEntity.Contains("ownerid") && !postImage.Attributes.Contains("ownerid")) return; Guid newOwnerId = ((EntityReference)postImage["ownerid"]).Id; // 获取新所有者的投资组合所有者ID Entity newOwner = service.Retrieve("systemuser", newOwnerId, new ColumnSet("new_portfolioowner")); if (!newOwner.Contains("new_portfolioowner")) { // 投资组合所有者为空时,清空自定义实体的分支/国家字段 Entity updateEntity = new Entity(targetEntity.LogicalName, targetEntity.Id); updateEntity["new_branch"] = null; updateEntity["new_country"] = null; service.Update(updateEntity); return; } Guid portfolioOwnerId = ((EntityReference)newOwner["new_portfolioowner"]).Id; // 获取投资组合所有者的分支与国家信息 Entity portfolioOwner = service.Retrieve("systemuser", portfolioOwnerId, new ColumnSet("new_branch", "new_country")); // 准备并执行自定义实体字段更新 Entity updateEntity = new Entity(targetEntity.LogicalName, targetEntity.Id); if (portfolioOwner.Contains("new_branch")) updateEntity["new_branch"] = portfolioOwner["new_branch"]; if (portfolioOwner.Contains("new_country")) updateEntity["new_country"] = portfolioOwner["new_country"]; service.Update(updateEntity); } catch (Exception ex) { throw new InvalidPluginExecutionException("同步分支/国家字段失败: " + ex.Message); } } }
关键注意事项
- 权限配置:确保插件执行的身份(如系统用户)拥有读取
systemuser实体、更新自定义实体的权限 - 异常兼容:针对投资组合所有者为空、字段不存在等场景做处理,避免插件报错中断业务
- 性能优化:通过
ColumnSet仅获取所需字段,减少数据传输量
测试验证
- 打开自定义实体的一条记录,修改其所有者为指定用户
- 保存记录后,查看
new_branch和new_country字段是否自动同步为该用户投资组合所有者的对应值 - 测试投资组合所有者为空的场景,确认字段是否按预期清空
内容的提问来源于stack exchange,提问作者user20971593
相关产品推荐
相关产品推荐

