C# 4.0 CRM插件将变量标志传递给新的执行管道
我有一些记录,它们有一个索引属性来保持它们彼此之间的位置 我有一个插件,当索引被更改或创建新记录时,它会对这些记录执行重新编号操作。有一些特定规则适用于列表中第一个和最后一个位置的项目 如果一个新的(或现有的已更改的)项目插入到列表的中间(从技术上讲不是中间…只是在开始和结束之间的某个地方),则会开始重新编号,以便为记录腾出空间 这个重新编号过程在一个新的执行管道中启动…我们正在更新记录D。当我告诉记录E更改(为D腾出空间)时,当然会在更新消息中启动插件 在我们到达列表的末尾之前,这种重新编号是可以的,在这里,插件进入一个循环,第一条业务规则以不同的方式维护第一条和最后一条记录 因此,我正试图想办法将标志传递给重新编号过程生成的执行上下文,以便在isRecumbering==true时递归跳过边界边缘业务规则 我的想法/想法: 我曾想过使用深度检查>1,但这不是一个可靠的值,因为我无法显式地打开或关闭它……它可能会正常工作,但这并不是一个希望什么都不会发生的工程解决方案。还有一位比我更了解情况的同事说,当工作流调用插件时,深度值是关闭的,不能信任C# 4.0 CRM插件将变量标志传递给新的执行管道,c#-4.0,dynamics-crm-2011,C# 4.0,Dynamics Crm 2011,我有一些记录,它们有一个索引属性来保持它们彼此之间的位置 我有一个插件,当索引被更改或创建新记录时,它会对这些记录执行重新编号操作。有一些特定规则适用于列表中第一个和最后一个位置的项目 如果一个新的(或现有的已更改的)项目插入到列表的中间(从技术上讲不是中间…只是在开始和结束之间的某个地方),则会开始重新编号,以便为记录腾出空间 这个重新编号过程在一个新的执行管道中启动…我们正在更新记录D。当我告诉记录E更改(为D腾出空间)时,当然会在更新消息中启动插件 在我们到达列表的末尾之前,这种重新编号是
我所有的变量都是在执行级别确定范围的,以避免类级别的变量污染…但是如果我有一个dictionary对象,tuple,类级别的一些东西,一个值是线程id,另一个值是标志值,那么我的后续执行上下文可能会检查同一个拥有线程id的线程是否输入了任何值
任何关于如何将上下文信息传递到新管道的想法或其他想法都将不胜感激
我试过共享变量,但它们似乎超出了范围…: 第一次射击后操作:
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);
}
}
现在我们进入了由上面的post-Op-OrganizationService.Update(renumrec)启动的递归过程的预操作阶段;根据这张支票,共享变量似乎没有结转
if (!Context.SharedVariables.Contains(recordrenumbering))
{
//Trace.Trace("Null Set");
//Context.SharedVariables[recordrenumbering] = IsRenumbering;
Context.SharedVariables[recordrenumbering] = "Null Set";
}
抛出InvalidPlugineException显示:
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
你在找什么。您在此处添加的内容在整个交易过程中都可用。因为有子管道,所以需要查看
ParentContext
中的值。这可能会有点棘手,所以一定要做大量的测试-我在Dynamics CRM中遇到了许多关于SharedVariables
和循环操作的问题
下面是一些示例(未经测试)代码,让您开始学习
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);
}
一个非常简单的解决方案:在名为“DisableIndexRecomulation”的实体中添加一个位字段。当您的第一个插件运行时,请确保为所有更新将该字段设置为true。在同一个插件中,检查“DisableIndexRecomulation”是否设置为true:如果设置为true,则将其设置为null(通过将其完全从TargetEntity中删除),并停止执行该插件。如果为空,请重新计算索引
因为如果该字段为真,您将立即从TargetEntity中删除该字段,因此该值将永远不会保留到数据库中,因此不会有性能损失。我认为当递归触发时,共享变量将超出范围…需要读取IsRecumbering标志的是递归触发…但从您的回答我在这一点上是错的,所以我将探究你所介绍的内容。非常感谢。请看我的编辑。也许我不理解实现。当你说在同一个插件中…(“在同一个插件中,检查“DisableIndexRecomulation”是否设置为true”)你的意思是在递归预操作过程中还是在第一次操作后通过?你将为预创建/预更新阶段注册一个插件。它首先检查是否应该禁止索引重新计算(DisableIndexRecalcuation=true)。如果是这样,它还会从TargetEntity中删除DisableIndexRecomulation字段,这样它就不会被持久化到db中。否则,它将重新计算索引。最终的结果是,您可以在“中间”创建一个记录,该插件将更新其所有同级索引,同时在每个更新上小心地设置DisableIndexRecalcuation,这样同级插件的执行也不会触发索引重新计算。