技术标签: dynamic programming Microsoft Dynamics 365 CE 扩展 Dynamics 365 CE microsoft
商用现货产品(COTS)对企业组织来说是有吸引力的选择,因为它们包含了可配置的开箱即用功能,可以在不编写任何代码的情况下满足大部分业务需求。Dynamics 365也不例外。Dynamics CRM 365专门提供功能强大的模块化功能丰富的产品,可根据您的组织需求进行定制。
一般来说,随着产品的发展,可配置的无代码扩展实现起来更便宜,维护起来更容易,升级起来也更容易。正确建模,这些扩展可以大大提高您的投资价值。如果建模不正确,它们可能会导致平台只锁定一个目的。
使用与Dynamics365套件相同的类比,您可以通过松散耦合实体来构建通用的CRM应用程序,也可以通过紧密耦合所有内容来构建专门的应用程序。以下图片取自Dynamics365 Microsoft营销包,显示了专门的实施与更通用的实施:
一个专门的实现并不一定是错误的,因为如果某些应用程序是通用的,就没有意义,尤其是当一些组织在孤立的业务单元中工作时。也就是说,大多数组织更喜欢更灵活的实施方式。
本章将介绍处理不同业务场景的不同模式建模技术,以及它们各自的优缺点。它还将涵盖在过去几年中引入的开箱即用的可配置业务逻辑扩展,这大大减少了配置实现所需的代码量。
为了给我们的配置提供上下文,我们将基于带有学生/联系人管理系统的大学解决方案对我们的实体进行建模。该系统将保留联系人,可以是普通个人、有毕业详细信息的学生,也可以是为学院工作的承包商。
通常,帐户和联系人实体是Dynamics CRM实现中最常用的实体。在大型实现中,这些实体通常也可用于多种目的。为了说明建模模式,这个方法将利用引言中描述的大学解决方案。我们将集中精力建立可以是个人也可以是学生的联系。每种类型的联系人都需要一组不同的属性。
建模多用途实体的最简单方法是将不同类型所需的所有属性添加到同一实体中。
为了配置架构,您需要访问Dynamics 365实例以及系统自定义程序或更高级别的安全角色。作为最佳实践,始终建议您在解决方案中实现配置。出于本书的目的,预计您已经创建了一个名为Packt的解决方案,其发行商前缀为Packt_。
就像数据库建模一样,实体可以规范化也可以非规范化。规范化一个结构是将其分离为几个相关的表,以减少冗余数据或空字段。反规范化结构则相反:我们将两个或多个表合并在一起,以简化结构并提高查询性能,同时添加冗余或空字段。在这个示例中,实体被反规范化,以允许不同类型的联系人通过同一联系人实体浮出水面。
在步骤1到步骤4中,我们将现有联系人实体添加到组件解决方案中。请注意,在步骤3中,我们可以选择添加必要的资产或添加所有资产。为了简化这个示例,我们添加了所有资产。通过最近的细粒度解决方案增强,我们可以简单地添加所需内容。
最佳做法是尽量减少解决方案中不必要的属性和关系的数量,以避免冲突和依赖关系。
在步骤5到步骤7中,我们创建了属性,在步骤8和步骤9中,我们将属性添加到一个新的联系人表单中。在步骤10中,我们发布了我们实现的配置。
为了避免多解决方案依赖关系以及表单被另一个解决方案的更新版本覆盖的情况,最佳实践要求您为解决方案创建一个新表单并将其标记为默认表单。如第9章Dynamics 365扩展中所述,使用应用程序可以隐藏不必要的表单。
从更新实体的设计来看,我们现在已经将联系人实体配置为实现多个目的:它是一个通用联系人,也是一个学生联系人。
简化实体关系(ER)图如以下屏幕截图所示:
非规范化模型的优点是:
非规范化模型的缺点是:
与数据库建模类似,非规范化模型的替代方案是,您猜到了,规范化模型。规范化结构是将一个表分离为两个或多个结构的操作。规范化减少了表单中多余或不必要字段的数量。在Dynamics365上下文中,通过在不同实体之间分布属性,同时保留一个公共父级,规范化将有助于避免一个实体过度拥挤。
在这个方法中,我们将继续使用联系人实体,并扩展其关系以包括其他属性:学生毕业详细信息。
与之前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
尽管这个方法被简化了,但典型的规范化模型将包含多个属性以及多个实体。
在步骤2到步骤11中,我们创建了一个标准化实体,该实体包含员工详细信息及其快速视图。在第4步中,我们避免勾选复选框。所有带有符号的复选框都显示了无法恢复的选项。如果需要,我们随时可以稍后启用它们。作为最佳实践,如果不需要它们,请不要启用它们,否则您的选择将是不可逆转的。在步骤12和步骤13中,我们创建了联系人和新创建的实体之间的关系,以提供父联系人实体和特定类型的附加属性(主管和研究生毕业日期)之间的导航路径。在最后的步骤(步骤14到步骤18)中,我们在联系人表单上添加了查找和快速查看。快速查看是另一条记录的简化子视图,可以放在父记录的表单上,以只读方式显示子记录的属性子集。以下屏幕截图中的红色框突出显示了与毕业详细信息查找记录相关的快速查看:
通过这种设计,我们现在可以在联系人表单上看到毕业生的详细信息,而无需在实体本身上创建属性。
我们的ER图现在是这样的:
使用通用父级规范化数据的优势在于:
使用快速视图,用户可以检索两级深度的数据。相关记录的属性及其1:N或N:N相关列表。
这种模式也有一些缺点,如下所示:
第三种建模技术与第二种类似,只是实体是完全独立的。当实体之间存在逻辑分离,并且它们之间几乎没有共性,以至于重用性不合理时,通常会使用此场景。
在这个方法中,我们将创建一个名为contractor的新实体,该实体通过一些附加字段来镜像联系人实体。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置,以及包含更改的解决方案。
前两种建模模式的替代方案是保持实体完全分离。这可能被证明是一个有效的设计,因为它最大限度地提高了实例的多样性。您可以创建大量实体,而不会过度拥挤,也不会出现功能重叠。尽管如此,作为一种最佳实践,尽可能提高可重用性。请记住,Dynamics 365联机实例对可以创建的自定义实体的数量有限制。该限制还包括通过部署第三方解决方案引入的自定义实体。在撰写本文时,限制为每个Dynamics365实例300个自定义实体。您可以通过导航到“设置”|“管理”|“使用中的资源”来检查您的限制:
新ER图在以下屏幕截图中突出显示:
完全规范化模型的优点是:
这种模式也有一些缺点,其中包括:
商业规则是超级用户的梦想成真。它们最大限度地减少了表单上所需的自定义JavaScript的数量,并且当规则的作用域在实体级别时,它们可以替换一些简单的计算插件。
在本例中,我们将创建一个简单的业务规则,根据本章第一个方法中定义的联系人类型来显示和隐藏Student Id属性。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
我们首先在步骤3中将字段标记为默认隐藏。作为一种最佳实践,与加载记录时隐藏可见字段相比,当隐藏字段被显示时,它总是能提供更好的用户体验。在步骤7和步骤8中,我们创建了显示字段的条件和规则;在步骤9和步骤10中,我们创建了相反的条件和规则来隐藏字段。在实现业务规则时,请始终考虑相反的场景,否则,您将面临不可逆转的行动。
考虑到业务规则的范围已设置为默认的All Forms(编辑业务规则时为右上角),所有表单现在都将遵守该规则。如果范围设置为Entity,则该规则也将在服务器端触发,如果实现在表单外操纵数据时需要遵守的计算规则(例如,可编辑网格、批量导入或通过Web API或SDK),则这可能很有用:
在幕后,JavaScript功能是为了满足规则的要求而创建的。这在遵循一次配置、处处部署设计模式的所有形式因素中也得到了尊重。
业务规则也有限制,如下所示:
有关其他限制,请访问Create and edit business rules | Microsoft Learn
业务规则提供了一系列可以执行的操作。其中包括以下内容:
TechNet文章(Create business rules and recommendations to apply logic in a form | Microsoft Learn)涵盖了有关业务规则的更多详细信息。
工作流是您可以在Dynamics365中配置的最强大的无代码扩展之一;不需要任何代码,就可以自动化重复的业务流程。
工作流是通用的,可以实现广泛的功能,从创建实体、发送电子邮件到调用操作。在这个示例中,我们将创建一个工作流,在创建记录24小时后向任何新学生发送电子邮件。
与前面的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
在步骤2到步骤4中,我们创建了一个在创建时触发的工作流(当首次创建联系人记录时,工作流将开始等待)。如果我们想再次触发工作流,也可以根据需要调用工作流。在本例中,联系人可能已经创建,但不是学生。一旦联系人被设置为学生,就可以手动触发工作流来发送欢迎电子邮件。
在步骤5和步骤6中,我们将等待条件设置为等待一天。
在步骤7和步骤8中,我们检查联系人是否是具有电子邮件地址的活跃学生。
在步骤9到步骤12中,我们为联系人创建了一封个性化的电子邮件,并对他们表示欢迎。
在步骤13中,我们激活了工作流。
作为一种良好的做法,请始终在工作流和每个步骤中添加描述,以便从更高的层次了解工作流在做什么。
当异步工作流被触发时,它们会进入一个池,以便在异步服务空闲时进行处理。异步工作流通常在几秒钟或几分钟内执行。如果执行需要数小时,那么您可能需要向Microsoft提出support ticket以进行调查。异步执行工作流是减轻Dynamics实例负载的好方法。
当工作流实例等待满足某个条件时,它们不会消耗资源或影响实例的性能。然而,社区普遍认为,让太多工作流实例处于等待状态是一种糟糕的做法。
在最近的版本中,可以将工作流转换为可配置插件的同步工作流变得可用。由于与长流程相关的负载,Microsoft不建议将同步工作流用于长流程。此外,每个同步工作流或插件的联机实例的时间限制为2分钟。尽管如此,还是可以使用同步工作流。明智地使用它们。
你有没有想过用JavaScript调用工作流?如果您有,那么您将很高兴了解Actions。Dynamics CRM 2013引入的Actions是可配置扩展的又一大补充。它的创建是为了允许从工作流中调用业务逻辑,以及从JavaScript和插件自定义中调用。
可以使用点击界面和.NET代码构建Action。在这个方法中,我们将创建一个配置的动作,该动作采用一些字符串值,创建一个学生记录,并将该记录作为输出参数返回。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
在步骤2和步骤3中,我们创建了空白操作。我们确保操作的实体设置为None(全局),这意味着流程不绑定到任何实体(工作流的方式)。
在步骤4中,我们创建了三个输入参数和一个输出参数。
在步骤5到步骤7中,我们使用输入参数创建了学生联系记录。
在步骤8到步骤10中,我们将创建的记录分配给输出参数。
在步骤11中,我们激活了流程。
如前所述,可以从工作流、JavaScript、插件或使用Dynamics365 web服务调用操作。每次创建操作时,Dynamics365都会创建一条可以从外部调用的消息。在第4章“服务器端扩展”中的“创建您的第一个自定义操作方法”中,您将学习如何为要使用托管.NET代码调用的操作生成早期绑定类型。
Microsoft建议使用描述操作内容的动词来命名操作,以确保应用程序的词汇表从业务流的角度来看是有意义的。
有关操作的更多信息,请访问Actions | Microsoft Learn
第4章“服务器端扩展”的“创建您的第一个自定义操作方法”
汇总字段是近年来引入的最令人兴奋的新功能之一,它大大减少了所需的自定义代码量。汇总字段可以聚合其他属性的值。您可以计算总和、平均值、最小值、最大值和计数。
在这个方法中,我们将创建一个汇总字段,统计有多少活动与一个联系人关联。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
在步骤2到步骤7中,我们创建了一个类型为整数的新汇总字段,用于计算与联系人关联的活动总数。
关于汇总字段有几点需要注意:字段是只读的,计算不考虑用户的安全角色。
创建汇总字段时,在后台,系统异步作业计划在创建字段后12小时执行。导航到“设置”|“系统作业”;您将在系统作业名称中看到一个类型为“Mass Calculate Rollup”字段的作业,其中包含新字段的名称。单击“操作|推迟”并输入较早的日期/时间,可以强制作业提前运行。当您在生产环境中有大量记录时,不建议这样做。作业第一次运行时,必须更新所有字段,这可能会对性能产生影响。
随后,“系统作业”选项将为每个配置了汇总字段的实体提供一个“计算汇总”字段。默认情况下,后续汇总字段计算将每小时进行一次(这是最快的计划)。如果不需要每小时更新一次,可以通过双击“系统作业”选项并选择“操作”|“修改周期”来更新值。这将显示一个对话框,帮助您重新定义执行周期:
假设汇总字段是作为异步作业执行的,如果没有进行计算,请考虑检查异步服务的状态。对于内部部署安装,请登录到后端服务器并检查其状态。对于在线实施,请与Microsoft进行支持通话,以检查服务的状态。
除了自动调度之外,还可以通过执行CalcualteRollupFieldRequest以编程方式执行汇总字段。此外,如果您在线搜索“汇总字段工作流”,您会发现社区构建的自定义工作流活动,以强制在可配置的工作流中重新计算。
汇总字段是Dynamics365中的一个强大功能。除了本示例中描述的计数功能外,汇总字段还提供其他类型的聚合。此外,在某些情况下(活动),聚合可以跨越多个关系级别。
计算记录数是汇总字段的众多功能之一。假设字段类型允许,您还可以获得字段的最大值、最小值、平均值和总和。当您选择不同的聚合函数时,实体字段将相应地进行筛选
鉴于我们的汇总字段是汇总活动,该字段还可以通过在间接相关活动下定义活动方(活动)来包括间接相关活动。这将扩大聚合,不仅当联系人在相关领域,而且在当事方领域。
有关汇总字段的更多详细信息,请访问Define rollup fields | Microsoft Learn
与汇总字段类似,计算字段是Dynamics365配置功能的又一新增功能,可显著减少对自定义代码扩展的需求。
顾名思义,计算字段允许您根据另一个字段、函数或公式设置属性的值。此外,计算的字段可以基于一组条件来触发。
在本例中,我们将配置一个字段来计算两个日期之间的月份差异:(学生开始日期和学生结束日期)。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
在这个方法中,我们使用点击配置来设置一个计算字段,以计算毕业生的开始日期和结束日期之间的月数差异。
在第5步和第6步中,我们定义了条件,在第7步中,定义了计算公式。
计算字段转换为同步服务器端代码执行。它们类似于插件,并且在更新后或创建消息的执行流水线的阶段40期间执行。
假设执行发生在服务器端,则用户只有在触发保存事件后才能看到更改。与业务规则和JavaScript自定义不同,结果不是即时的。在表单前端满足条件后,它们不会触发。
与汇总字段类似,计算字段是只读的,不考虑用户的安全角色。
计算字段是一个强大的补充;它们可以用于许多场景,其中一些场景是:
TechNet文章(Define calculated fields | Microsoft Learn)在几个例子中介绍了计算字段。本文还介绍了计算字段的一些局限性。其中包括以下内容:
除了基本的算术运算外,Dynamics 365还支持以下内置公式及其各自的返回类型:
函数语法 | 返回值类型 |
ADDDAYS (whole number, date and time)
|
日期和时间 |
ADDHOURS (whole number, date and time)
|
日期和时间 |
ADDMONTHS (whole number, date and time)
|
日期和时间 |
ADDWEEKS (whole number, date and time)
|
日期和时间 |
ADDYEARS (whole number, date and time)
|
日期和时间 |
SUBTRACTDAYS (whole number, date and time)
|
日期和时间 |
SUBTRACTHOURS (whole number, date and time)
|
日期和时间 |
SUBTRACTMONTHS (whole number, date and time)
|
日期和时间 |
SUBTRACTWEEKS (whole number, date and time)
|
日期和时间 |
SUBTRACTYEARS (whole number, date and time)
|
日期和时间 |
DIFFINDAYS (date and time, date and time)
|
整数 |
DIFFINHOURS (date and time, date and time)
|
整数 |
DIFFINMINUTES (date and time, date and time)
|
整数 |
DIFFINMONTHS (date and time, date and time)
|
整数 |
DIFFINWEEKS (date and time, date and time)
|
整数 |
DIFFINYEARS (date and time, date and time)
|
整数 |
CONCAT (single line of text, single line of text, ... single line of text)
|
字符串 |
TRIMLEFT (single line of text, whole number)
|
字符串 |
TRIMRIGHT (single line of text, whole number)
|
字符串 |
设置汇总字段
自早期版本的Dynamics CRM以来,重复检测就一直存在。2015年,引入了替代密钥,以帮助根据执行追加销售请求的唯一属性组合来识别记录。追加是指根据主键标识符插入新记录,或更新已存在的记录(Use Upsert to insert or update a record | Microsoft Learn)。从逻辑上讲,这意味着无论何时定义备用密钥,使用相同密钥组合创建的任何新记录都将引发重复的异常。
这个方法将帮助我们定义联系人的备用密钥,并测试重复检测。
与以前的方法类似,需要系统自定义程序或更高的安全角色来执行配置以及包含更改的解决方案。
在步骤2到步骤5中,我们使用个人的名字、姓氏和电子邮件创建了一个备用键。在步骤6中,我们通过创建两个具有相同键组合的记录来测试重复检测。
备用键的行为与传统的重复检测类似,只是检查发生在数据库的较低级别(唯一的非聚集索引)。此外,如果检测到重复,主键将严格阻止创建重复,而传统的重复检测功能仍然可以选择创建它。如果您想在使用与前端表单不同的通道时停止重复,这一点尤为重要。
在幕后,Dynamics CRM正在使用键中定义的三个字段创建一个非聚集的唯一索引。如果您有内部部署,则可以运行SQLprofiler来拦截在数据库上执行的命令。类似于以下查询的查询将出现在您的列表中:
前面的查询在ContactBase(联系人表)的三列上创建了一个唯一的非聚集索引:FirstName、LastName和EmailAddress1。有关非聚集索引的更多信息,请阅读以下文章Create Nonclustered Indexes - SQL Server | Microsoft Learn
在重复检测过程中,如果某个字段中有一个空值(在数据库中转换为NULL),则该记录将不会被标识为重复。
请注意,创建备用密钥有时会失败。创建密钥后,请始终检查创建是否成功。如果数据集中已经存在重复项,则密钥创建将失败。要检查新创建的密钥的状态,请在解决方案中导航到“实体”|<your entity>|Keys,并确保“状态”列处于“活动”状态。如果创建失败,它将显示Failed(失败):
文章浏览阅读1.5w次,点赞53次,收藏682次。目录1、写在前面的话2、常用命令2.1、常用命令的使用:2.1.1、pwd命令2.1.2、cd命令2.1.3、cp命令2.1.4、mv命令2.1.5、chmod命令2.1.6、ls命令2.1.7、rm命令2.1.8、rmdir2.1.9、touch命令2.2.0、gzip命令2.2.1、tar命令2.2.2、mail命令2.2.3、wall命令3、心得体会1、写在前面的话在我们使用Linux系统时,学..._linux -exec命令
文章浏览阅读1.4w次。在mybatis的configure文件中增加typehandler:<configuration><typeHandlers> <typeHandler handler="com.test.framework.utils.MyStringTypeHandler" javaType="java.lang.String" jdbcType="C..._mybatis去除前后空格
文章浏览阅读5.4k次。TP-link无线网卡官方驱动不支持Ubuntu20,经过查找资料,遇到问题,不断尝试之后得到解决!_ubuntu tplink无线网卡驱动
文章浏览阅读2.3k次,点赞2次,收藏10次。使用工具:eclipse步骤:1、运行eclipse2、选择需要打包成jar包的java文件3、右击选择-->Export4、选择Java下面的JAR file-->next5、勾选如下图,然后Next-->Next注意:JAR file输入框中需要填写打包好的jar文件存放的目录6、确认需要打包的文件,如下图选择好之后,点击fi_java如何打包成压缩后jar包
文章浏览阅读7.9k次,点赞83次,收藏416次。大家前面学过Python基础知识的都知道,Python为我们封装了列表、字典等高级数据类型,并且他们都带有一系列增、删、改、除的方法,让我们能够很方便的处理一些问题。以目前我们这些人的技术水平可能觉得这些东西就够了,照样能够快速的解决很多的问题。可是随着知识的深..._python封装好的数据结构
文章浏览阅读199次。计算机应用能力考试教材:Windows XP操作系统(题库版)语音编辑锁定讨论上传视频《计算机应用能力考试教材:WindowsXP操作系统(题库版)》是2011年电子工业出版社出版的图书,作者是全国专业技术人员计算机应用能力考试专家委员会。书名计算机应用能力考试教材:Windows XP操作系统(题库版)作者全国专业技术人员计算机应用能力考试专家委员会ISBN97871211364..._计算机应用能力考试windows xp
文章浏览阅读4.4k次。一、板级电路整体架构我接下来一段时间学习的就是“勇敢的芯”FPGA 实验平台,它是特权同学和至芯科技携手打造的一款基于Altera Cyclone IV FPGA 器件的入门级 FPGA 学习平台FPGA 实验板实物图如图所示这是整板的外设器件的示意图。FPGA 实验板接口芯片连接如图所示二、电源电路与任何电子元器件一样,FPGA 器件需要有电源电压的供应才能工作。尤其对于规模较大的器件,其功耗也相对较高,其供电系统的好坏将直接影响到整个开发系统的稳定性。所以,设计出高效率、高性能的 FP_板级电路是什么
文章浏览阅读2.6k次,点赞2次,收藏4次。注:用static去定义一个注入的方法或者配置文件值变量,编译时不会有任何异常,运行时会报空指针。Spring官方不推荐此种方法。原理:https://www.cnblogs.com/chenfeng1122/p/6270217.html解决办法利用spring的set注入方法,通过非静态的setter方法注入静态变量 ,我们可以改成这样就静态变量可以获取到你配置的信息了。把get,set方法的static 修饰符去掉,然后在set方法上面加@Autowired即可/*.._springboot autowired static
文章浏览阅读2.1w次,点赞15次,收藏22次。最近有点闲,就学习了下react,没想到就把react学完了,觉得还不错,就打算出一把react+datav的简易版可视化数据大屏供大家做个参考。 datav框架 echarts2,路由设计 在路由上,我是绑定一个index的路由作为组件,然后在index添加自适应的全局容器,当容器设置完成后,就在就在将其他的小的模块给一个个导入进来, _用react写数据可视化大屏
文章浏览阅读4.2k次。人工智能:文本去掉停用词stopwords为了彻底搞懂本质,写的非常细!(1)准备停用词import pandas as pdimport jieba# 准备停用词stopwords = pd.read_csv("data/stopwords.txt", index_col=False, quoting=3, sep='\t', names=['word'], encoding='u..._nlp 去除停用词
文章浏览阅读504次。vs资源试图添加窗口可修改ID,会自动创建对于ID数据的,在.h文件中enum { IDD = IDD_XXX};中可以使用类视图添加窗口消息_类视图消息
文章浏览阅读10w+次,点赞413次,收藏1.3k次。简介JRebel是一套JavaEE开发工具。Jrebel 可快速实现热部署,节省了大量重启时间,提高了个人开发效率。JRebel是一款JAVA虚拟机插件,它使得JAVA程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。JRebel使你能即时分别看到代码、类和资源的变化,你可以一个个地上传而不是一次性全部部署。当程序员在开发环境中对任何一个类或者资源作出修改的时候,这..._jrebel