我有一个CRM自定义插件,该插件已通过创建活动事件注册(通过CRM插件注册工具)。 “创建”是消息,“工作”是主要实体。
在创建新工作时,我要接受该实体并自动为其分配项目编号。我始终将“事件执行的事件管道阶段”设置为“操作后”。我已经尝试了两种执行模式(异步和同步)。
异步总是向我抛出## First function: #==================================
reg <- function(steps, r){
x <- diag(steps+1)
data.frame(r^abs(row(x)-col(x)))
}
## Second function: #==================================
foo <- function(long = c(1, 3, 2), r = .5){
g <- reg(max(long, na.rm = T), r)[,1][-1] ## from the first function
r <- ifelse(long == 1, g[1], ifelse(long == 2) g[2] # . . . ## if. . . how many ifelse needed?
return(r)
}
同步永远不会引发错误,但是我的工具中的任何代码都没有执行。
"Entity job with ID '' does not exist"
我也尝试过 public void Execute(IServiceProvider serviceProvider)
{
var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var orgService = factory.CreateOrganizationService(null);
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity ent = (Entity)context.InputParameters["Target"];
IOrganizationService service = factory.CreateOrganizationService(null);
if (ent.LogicalName == "cmc_job")
{
try
{
ent["cmc_jobnumber"] = "0000001";
ent["cmc_name"] += " - DEMO";
service.Update(ent);
}
catch (Exception e)
{
Console.Write(e.Message);
}
}
,但是我也经常遇到错误。这些错误通常与重复记录有关。另外,我确保取消与创建作业有关的任何现有流程。
创建实体后,如何立即正确更新实体字段?哪种做法最好?
附带说明:之所以决定使用CRM自定义插件而不是自定义流程是因为我需要查询现有的最大项目编号,然后再添加1。
答案 0 :(得分:2)
对于自动编号插件,最佳实践是在预操作(同步)上进行注册。这样,将在创建记录的同一数据库事务中设置自动编号的字段(避免不必要的事务和混乱的审核历史记录)。
在编写术前插件时,您不应调用service.Update(),而只需在目标上设置值(如您当前所用),它们将与目标的其他属性一起保留。注释掉您的service.Update()行,您的插件应该可以在预操作中使用。
异步总是向我抛出“不存在ID为的实体作业”的错误
同步永远不会引发错误,但是我的工具中的任何代码都没有执行
之所以会这样,是因为在创建过程中,直到将记录持久化到数据库之前,才将ID分配给记录。您正在使用目标(没有ID),然后尝试执行service.Update(),该服务需要具有ID的实体。同步和异步调用都会引发错误,但是异步错误会在后台发生,您看不到它。
答案 1 :(得分:1)
您必须重新检查PRT中的异步步骤注册。
每当您在帖子管道中访问刚创建的记录ID时,由于数据库事务尚未提交,同步插件将失败。
但是异步插件将成功,因为数据库事务已提交并且可以通过ID进行记录。
无论如何,最佳做法是在操作前本身设置所需的属性值,以避免再次进行显式更新服务调用。您可以在SO本身,Dynamics社区和互联网博客中找到很多类似的accepted answers,它们具有相同的建议。