背景

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

传统的做法:

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. 如何将SQL Server 2000备份的数据库文件还原(升级)为SQL Server 2005或更高版本的数据库?

    其实很简单,有两种方法. 方法一:将SQL Sever 2000数据库备份的数据库文件名后面加上“.bak”,然后直接在SQL Sever 2005或者高版本软件里面直接还原即可: 方法二:在SQL ...

  2. mysql client之init-command

    If the server is a replication master and you want to avoid replicating the content to replication s ...

  3. MySQL中的xtrabackup的原理解析

    xtrabackup的官方下载地址为 http://www.percona.com/software/percona-xtrabackup. xtrabackup包含两个主要的工具,即xtraback ...

  4. python基础学习22----协程

    协程,又称微线程.英文名Coroutine. 协程最大的优势就是协程极高的执行效率.因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就 ...

  5. kettle 启动spoon一闪而过

    Kettle是Pentaho的一个组件,主要用于数据库间的数据迁移(ETL). Kettle有三个主要组件:Spoon,Kitchen,Pan.其中Spoon是一个图形化的界面. 一.安装kettle ...

  6. MySQL基础之 索引

    MySQL索引讲解 索引的好处: MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么 ...

  7. 记录使用git submodule时踩的坑

    在使用git子模块的时候踩了一个坑 在使用git submodule updata --init --recursive命令,即递归更新子模块并初始化时碰到了一个问题: 经过一段不短时间的排查,发现问 ...

  8. SDN期末作业-通过SDN的应用实现负载均衡

    负载均衡程序 1.程序链接:https://github.com/424baopu/software/tree/master/LoadBalance 2.场景 topo: 场景描述: 服务器host ...

  9. 解决The valid characters are defined in RFC 7230 and RFC 3986错误问题

    分析原因: 导致上述问题是因为tomcat自tomcat 8.0.35版本之后对URL参数做了比较规范的限制,必须遵循RFC 7230 and RFC 3986规范,对于非保留字字符(json格式的请 ...

  10. 使用vs2010编译lua5.1源代码生成lua.lib

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wangbin_jxust/article/details/37557807 一.打开vs2010 二 ...