CRM PlugIn将变量标志传递给新的执行管道

时间:2014-07-07 21:17:42

标签: c#-4.0 dynamics-crm-2011

我的记录具有索引属性以保持彼此之间的位置。

我有一个插件,可以在更改索引或创建新索引时对这些记录执行重新编号操作。有一些特定的规则适用于列表中第一个和最后一个位置的项目。

如果一个新的(或现有的已更改)项目被插入到列表的中间(技术上不是中间......就在开始和结束之间的某个位置),则重新编号将开始为记录腾出空间。

这个重新编号的过程在一个新的执行管道中触发......我们正在更新记录D.当我告诉记录E改变(为D腾出空间)当然会在更新消息上触发插件。

这个重新编号是好的,直到我们到达列表的末尾,然后插件进入循环,第一个业务规则以不同方式维护第一个和最后一个记录。

所以我试图想办法将标志传递给重新编号过程产生的执行上下文,这样如果IsRenumbering == true,递归会跳过边界边缘业务规则。

我的想法/想法:

我想过使用深度检查> 1,但这不是一个可靠的值,因为我无法明确地打开或关闭....它可能会发生工作,但这并不是一个可靠的解决方案,希望没有任何事情发生。另外一位同事比我说的更了解当工作流程调用插件时深度值已关闭且无法信任。


我的所有变量都在执行级别作用域,以避免类级别的变量污染....但是如果我有一个字典对象,元组,类级别的东西和一个值将是线程ID和另一个是标志值,那么也许我的后续执行上下文可以检查相同的拥有线程id是否输入了任何值。


关于如何将上下文信息传递给新管道的任何想法或其他想法将不胜感激。


Per Nicknow sugestion我尝试了共享变量,但它们似乎超出了范围......:

第一次解雇后:

if (base.Stage == EXrmPluginStepStage.PostOperation)
{
 ...snip...

    foreach (var item in RenumberSet)
    {
       Context.ParentContext.SharedVariables[recordrenumbering] = "googly";

       Entity renumrec = new Entity("abcd") { Id = item.Id };

          #region We either add or subtract indexes based upon sortdir
               ...snip...
               renumrec["abc_indexfield"] = TmpIdx + 1;
               break;
               .....snip.....
          #endregion

         OrganizationService.Update(renumrec);
      }

}

现在我们进入上面的op-OrganizationService.Update(renumrec)开始的递归过程的Pre-Op;似乎基于这个检查,共享变量没有结转...... ???

 if (!Context.SharedVariables.Contains(recordrenumbering))
 {
   //Trace.Trace("Null Set");
   //Context.SharedVariables[recordrenumbering] = IsRenumbering;
   Context.SharedVariables[recordrenumbering] = "Null Set";
 }

throw invalidpluginexception揭示:

 Sanity Checks:
    Depth : 2
    Entity: ...
    Message: Update
    Stage: PreOperation [20]
    User: 065507fe-86df-e311-95fe-00155d050605
    Initiating User: 065507fe-86df-e311-95fe-00155d050605
ContextEntityName: ....
ContextParentEntityName: ....
....
IsRenumbering: Null Set

2 个答案:

答案 0 :(得分:1)

你在寻找什么是IExecutionContext.SharedVariables。无论您在此处添加什么,都可以在整个交易中使用。由于您将拥有子流水线,因此您需要查看值ParentContext。这一切都有点棘手,所以一定要做很多测试 - 我遇到了很多SharedVariables问题和Dynamics CRM中的循环操作。

以下是一些示例(非常未经测试的)代码,可帮助您入门。

    public static bool GetIsRenumbering(IPluginExecutionContext pluginContext)
    {
        var keyName = "IsRenumbering";
        var ctx = pluginContext;

        while (ctx != null)
        {
            if (ctx.SharedVariables.Contains(keyName))
            {
                return (bool)ctx.SharedVariables[keyName];
            }
            else ctx = ctx.ParentContext;
        }

        return false;
    }

    public static void SetIsRenumbering(IPluginExecutionContext pluginContext)
    {
        var keyName = "IsRenumbering";
        var ctx = pluginContext;

        ctx.SharedVariables.Add(keyName, true);
    }

答案 1 :(得分:0)

一个非常简单的解决方案:向名为“DisableIndexRecalculation”的实体添加一个位字段。当您的第一个插件运行时,请确保为所有更新将该字段设置为true。在同一个插件中,检查“DisableIndexRecalculation”是否设置为true:如果是,请将其设置为null(通过完全从TargetEntity中删除它)并停止执行插件。如果为null,请执行索引重新计算。

因为您正在立即从TargetEntity中删除该字段,如果该字段为true,则该值将永远不会保留到数据库中,因此不会有性能损失。