背景

经常有某个汇总子表的数量到主表的总数量,或者汇总子表的总价到主表的总价这种需求。

传统的做法:

1、就是为每个子表实体单独写成一个插件,但是这样不好复用。

2、主表的汇总字段是汇总货币类型,但是不能实时计算,得手动在页面上重新计算,如下图,点刷新才会触发计算

这里有幸阅读了网上一位前辈【疯吻IT】4年前写的文章,继承了他的思路实现了增删改重新触发汇总子表的某个字段到主表某个字段上。

效果图:

话不多说,上代码。

#region << 版 本 注 释 >>
/*----------------------------------------------------------------
* 项目名称 :Vyung.CRM.Plugins.Plugin
* 项目描述 :
* 类 名 称 :SumSub2Head
* 类 描 述 :将子表的字段合计到头表的某个字段
* 增删改实时触发头表汇总字段更新
* 所在的域 :cangfeng-PC
* 命名空间 :Vyung.CRM.Plugins.Plugin
* 机器名称 :CANGFENG-PC
* CLR 版本 :4.0.30319.42000
* 作 者 :cangfeng
* 创建时间 :2018/11/28 13:23:28
* 更新时间 :2018/11/28 13:23:28
* 版 本 号 :v1.0.0.0
*******************************************************************
* Copyright @ cangfeng 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Vyung.CRM.Plugins.Common; namespace Vyung.CRM.Plugins.Plugin
{ public class SumSub2Head : IPlugin
{
//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount
public static string unsecure = "";
public SumSub2Head(string unsecureConfig, string secureConfig)
{
if (String.IsNullOrWhiteSpace(unsecureConfig) ||
String.IsNullOrWhiteSpace(unsecureConfig))
{
throw new InvalidPluginExecutionException("Unsecure and secure strings are required for this plugin to execute.");
} unsecure = unsecureConfig;
}
public void Execute(IServiceProvider serviceProvider)
{
#region 上下文实体信息初始化
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);
IOrganizationService serviceAdmin = serviceFactory.CreateOrganizationService(null);
bool isCreate = context.MessageName == "Create";
bool isUpdate = context.MessageName == "Update";
bool isDelete = context.MessageName == "Delete";
Entity target = null;
EntityReference targetref = null; //当前的实体
Entity m_CurrentEntity = null; if (context.InputParameters.Contains("Target"))
{
if (context.InputParameters["Target"] is Entity)
target = (Entity)context.InputParameters["Target"];
else if (context.InputParameters["Target"] is EntityReference)
targetref = (EntityReference)context.InputParameters["Target"];
}
Guid entityId;
string logicalName;
if (target == null)
{
entityId = targetref.Id;
logicalName = targetref.LogicalName;
}
else
{
entityId = target.Id;
logicalName = target.LogicalName;
}
#endregion #region 基本实体信息初始化
Entity preEntity = null;
Entity postEntity = null; if (context.PreEntityImages.Contains("PreImage") && context.PreEntityImages["PreImage"] != null)
{
preEntity = context.PreEntityImages["PreImage"];
}
if (context.PostEntityImages.Contains("PostImage") && context.PostEntityImages["PostImage"] != null)
{
postEntity = context.PostEntityImages["PostImage"];
}
int intStage = context.Stage;
#endregion try
{
//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount
var param = unsecure.Split(','); #region 前期事件
if (intStage == 10 || intStage == 20)
{
#region 创建事件
if (isCreate)
{ }
#endregion #region 更新事件
if (isUpdate)
{ }
#endregion #region 删除事件
if (isDelete)
{ }
#endregion }
#endregion #region 后期事件给m_CurrentEntity赋值
else
{
#region 创建事件
if (isCreate)
{
m_CurrentEntity = target;
}
#endregion #region 更新事件
if (isUpdate)
{ //m_CurrentEntity = (Entity)context.InputParameters["Target"];
m_CurrentEntity = target;
m_CurrentEntity[param[1]] = preEntity[param[1]]; }
#endregion #region 删除事件
if (isDelete)
{
//我擦,删除居然不是entity类型,坑人targetref
//EntityReference er = context.InputParameters["Target"] as EntityReference;
//m_CurrentEntity = new Entity(er.LogicalName);
//m_CurrentEntity.Id = er.Id;
//m_CurrentEntity[param[1]] = preEntity[param[1]]; m_CurrentEntity = new Entity(targetref.LogicalName);
m_CurrentEntity.Id = targetref.Id;
m_CurrentEntity[param[1]] = preEntity[param[1]];
}
#endregion
}
#endregion //获取当前记录的主表id,根据主表id使用Linq获取对应的其他明细记录的需要统计的字段。如:amount
OrganizationServiceContext svcContext = new OrganizationServiceContext(serviceAdmin);
var ents = svcContext.CreateQuery(m_CurrentEntity.LogicalName).Where(e => e[param[1]] == m_CurrentEntity[param[1]] && e[param[0]] != null).Select(e => e[param[0]]);
decimal amount = 0;
foreach (var ent in ents)
{
amount += Convert.ToDecimal(((Money)ent).Value);
} //根据当前记录的主表id,查出首条头记录
var primaryEnt = svcContext.CreateQuery(param[2]).Where(e => e[param[1]] == m_CurrentEntity[param[1]]).FirstOrDefault(); //给头的汇总字段赋值
if (primaryEnt != null)
{
primaryEnt[param[3]] = new Money(amount); //linq更新实体
svcContext.UpdateObject(primaryEnt);
svcContext.SaveChanges();
}
}
catch (Exception e)
{
throw new InvalidPluginExecutionException("错误:" + e.Message + "[" + this.GetType().ToString() + "]");
}
}
}
}

使用步骤:

1、准备好unsecureConfig字段,如下

//第一个参数是要被合计的子表字段,第二个参数是主表的主健,第三个参数是主表实体名,第四个参数是主表上显示合计值的字段。
//new_amounts,new_originalorderid,new_originalorder,new_totalamount

2、注册插件

3、注册步骤

create:

update:

update 的前镜像

delete:

delete的前镜像

Ok,插件写好之后,以后就只需要注册,并且在unsecureConfig配置好对应的汇总字段和表就OK了。

如果本文有帮助到你,就给个推荐吧O(∩_∩)O~

Microsoft Dynamics CRM 增删改子表汇总子表的某个字段到主表的某个字段(通用插件)的更多相关文章

  1. Microsoft Dynamics CRM 2011 当您在 大型数据集上执行 RetrieveMultiple 查询很慢的解决方法

    症状 当您在 Microsoft Dynamics CRM 2011 年大型数据集上执行 RetrieveMultiple 查询时,您会比较慢. 原因 发生此问题是因为大型数据集缓存 Retrieve ...

  2. Microsoft Dynamics CRM 2013 --选项集的多选

    由于从Microsoft Dynamics CRM 2011到Microsoft Dynamics CRM 2013,界面的风格发生了很大的变化 故原先在2011上开发的选项集多选在2013上面已经不 ...

  3. Microsoft Dynamics CRM 常用JS语法(已转成vs2017语法提示)

    背景 最近接触到Microsoft Dynamics CRM的开发.前端js是必不可少的部分,奈何没有一个语法提示,点不出来后续的语句. 在vscode上面搜索插件的时候发现,有一个大神写的插件htt ...

  4. Microsoft Dynamics CRM 分销行业解决方案

    Microsoft Dynamics CRM 分销行业解决方案 方案亮点 360度动态渠道信息管理 充分的客户细分 全面的业务代表考核指标 业务代表管理和能力建设 业务代表过程管理 业务代表费用管理 ...

  5. K2 BPM+Microsoft Dynamics CRM,妥妥的~

    啊~~~~七夕 ▼ 你比巴西少一xi 你比山西多四xi 对有情人来说今天就是情人节,对单身汪来说,今天就是个星期四. but,软件也是要秀恩爱的! ♥ 晒晒我家亲爱的CRM,它的全名叫Microsof ...

  6. 利用K2和Microsoft Dynamics CRM构建业务App的5大理由

    Microsoft Dynamics CRM提供了一个绝佳的客户关系管理平台,使您能够创建各种以客户为中心的解决方案.然而,通过将K2的企业业务流程功能与Microsoft Dynamics CRM相 ...

  7. 一、Microsoft Dynamics CRM 4.0 SDK概述

    Chapter 1. Microsoft Dynamics CRM 4.0 SDK Overview(SDK概述) You are probably reading this book because ...

  8. Dynamic CRM 2015学习笔记(6)没有足够的权限 - 您没有访问这些记录的权限。请联系 Microsoft Dynamics CRM 管理员

    我们经常遇到下面这种问题:没有足够的权限 - 您没有访问这些记录的权限.请联系 Microsoft Dynamics CRM 管理员.  下面将详细介绍下如何解决这种问题:进不了CRM系统:进了CRM ...

  9. Microsoft Dynamics CRM4.0 JScript 过滤lookup 出现 Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止。

    一.现象:JScript过滤lookup字段,选择lookup字段出现下图的情况: 出现:Microsoft Dynamics CRM 窗口无法打开,可能已被弹出窗口阻止程序所阻止.请将这台Micro ...

随机推荐

  1. 转:C# 深入理解堆栈、堆在内存中的实现

    尽管在.NET framework下我们并不需要担心内存管理和垃圾回收(GarbageCollection),但是我们还是应该了解它们,以优化我们的应用程序.同时,还需要具备一些基础的内存管理工作机制 ...

  2. PostgreSQL数据加载工具之pg_bulkload

    1. 介绍 PostgreSQL提供了一个copy命令的便利数据加载工具,copy命令源于PostgreSQL数据库,copy命令支持文件与表之间的数据加载和表对文件的数据卸载.pg_bulkload ...

  3. spark的shuffle和原理分析

    概述     Shuffle就是对数据进行重组,由于分布式计算的特性和要求,在实现细节上更加繁琐和复杂.    在MapReduce框架,Shuffle是连接Map和Reduce之间的桥梁,Map阶段 ...

  4. 解决ThinkPHP中开启调试模式无法加载模块的问题。

    刚开始学习ThinkPHP就遇到这种问题,还是自己粗心. 错误如下: 原因:开启调试模式,区分大小写的,要把模块名首字母大写就OK了.也就是: [plain] view plain copy http ...

  5. ab参数详解 – 压力测试

    命令参数:    -n requests     Number of requests to perform    //在测试会话中所执行的请求个数.默认时,仅执行一个请求    -c concurr ...

  6. python爬虫(二)

    python爬虫之urllib 在python2和python3中的差异 在python2中,urllib和urllib2各有各个的功能,虽然urllib2是urllib的升级版,但是urllib2还 ...

  7. 2.Redis集群环境搭建

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ 一.基本概念 1.redis集群是一个可以在多个节点之间进行数据共享的设施.redis集群提供了以下两个好处1 ...

  8. windows 下配置 Nginx 常见问题

    因为最近的项目需要用到负载均衡,不用考虑,当然用大名鼎鼎的Nginx啦.至于Nginx的介绍,这里就不多说了,直接进入主题如何在Windows下配置. 我的系统是win7旗舰版的,到官网下载最新版本 ...

  9. VS2010自行编译OpenCV2.4.4时缺少python27_d.lib的解决方法

    错误 24 error LNK1104: 无法打开文件“python27_d.lib”  C:\OpenCV\VS2013_64\modules\python\LINK opencv_python 编 ...

  10. 开源http协议库curl和wget的区别和使用

    curl和wget基础功能有诸多重叠,如下载等. 在高级用途上的curl由于可自定义各种请求参数所以长于模拟web请求,用于测试网页交互(浏览器):wget由于支持ftp和Recursive所以长于下 ...