通过插件计算子记录总和的策略

时间:2014-12-08 14:09:23

标签: dynamics-crm

考虑具有机会,报价,订单或发票等子记录的自定义实体。我想计算子记录的总和并将其保存到父记录。我尝试了几种方法,但每种方法都有一些缺点。

  1. 仅处理预操作总和的更改。加成 用于更新和减法的创建,减法和添加 删除。
  2. 问题:无法强制重新计算(重新计算 已存在的要素;错误后恢复)。它只适用 用于总和,但不用于其他聚合。

    1. 更改孩子会触发父母的完全重新计算 (后操作)。
    2. 问题:当孩子出现时,无法得到父母     已经删除(并且预操作为时尚早,无法重新计算)。该     完全重新计算应该更慢。

      1. 前一个的异步变体。同步预操作 一个孩子的触发器会触发异步重新计算父母。
      2. 问题:这可能效果很好,但它确实让用户感到困惑(他们     不要看到变化;他们无法立即打印报告。

        有没有更好的方法呢?也许结合1和2?我错过了什么吗?一般来说,这个问题似乎很容易。但考虑到MSCRM的SDK /限制,它变得越来越复杂。

2 个答案:

答案 0 :(得分:1)

关于聚合,我会为您提供一些选项(按复杂程度排列):

  1. 如果您不需要该功能,并且只需要在报告中显示聚合结果,请通过报告进行聚合计数。应该简单得多,节省时间。

  2. 在主页网格或记录表单上添加一个按钮,单击该按钮将更新某个记录的聚合。你可以通过插件或javascript计算来完成。当然,这需要用户采取行动。

  3. 您使用的选项具有以下逻辑:

    • PLUGIN ON CREATE(创建后),检查是否设置了父字段,如果是,则计算此实体的子记录总数,并使用计数更新父字段。所以不要添加一个,但要对所有记录进行计数。这样,如果插件之前失败,你就不会计算错误。
    • 在父级字段中更新(使用图像前置和后置更新后),使用总计数更新父记录的旧值和新值
    • PLUGIN ON DELETE(删除记录时的预操作),它将更新父记录中的记录总数,计算所有记录,而不记录最后一个记录。

      注意:应检查是否应该使用关联和解除关联的消息,但我认为更新时的插件将处理此问题。

  4. 制定定期工作流程,在自定义"聚合器上执行插件"实体,在工作流程中定义的特定时间段内。此插件必须查询所有父记录,并计算每个记录的聚合。您可以将此选项与前一个选项结合使用,也可以每天运行一次,以便正确更新数据。

答案 1 :(得分:0)

crmgenericrollup.codeplex.com提供此功能作为准备好的解决方案(由Guido Preite建议)通过计算子元素的插件中的字段并排除要删除的记录来解决这个问题(在PRE DELETE上) )

//third parameter for deleting
protected void CalculateAggregate(LocalPluginContext localContext, 
                                  RollupSettings rollupSetting, 
                                  bool ignoreThisRecord = false)
{
    if (ignoreThisRecord)
    {
        fetchXml = string.Format(@"
          <fetch distinct='false' mapping='logical' aggregate='true'> 
             <entity name='{0}'> 
               <attribute name='{1}' alias='A' aggregate='{2}'/> 
               <filter>
                 <condition attribute='{3}' operator='eq' value='{4}' />
                 <condition attribute='{5}' operator='neq' value='{6}' />
               </filter>
              </entity> 
          </fetch>", 
          rollupSetting.ChildEntity, rollupSetting.ChildEntityAttribute, 
          rollupSetting.RollupType.ToString(), rollupSetting.LookupAttribute, 
          rollupSetting.ParentEntity.Id.ToString(), rollupSetting.ChildEntityIdColumn, 
          localContext.PluginExecutionContext.PrimaryEntityId.ToString());
    }
    else
    {
      // ...
    }
 }

效果很好。我只是错过了强制重新计算的机会。如果需要,我意识到我可以不同地通知父记录有关被排除的记录。

我的解决方案在父记录上使用字段new_recalculate(日期时间)。它的更改(通过插件,工作流程,手动)会触发重新计算,并且还会保留上次重新计算的时间。

现在,有两种可能性可以继续。 1)通过设置字段new_beingdelete = true在删除前标记子实体,并从计算中排除带有此标志的子项。 2)在删除子项之前将子项的id保存到父项的查找字段,并在汇总中将其排除。第二种选择似乎更复杂,但如果允许更改父级记录,则更合适。