【问题标题】:Context message for UPDATE is not workingUPDATE 的上下文消息不起作用
【发布时间】:2012-11-07 14:56:02
【问题描述】:

我正在开发 CRM Dynamics 插件。自定义实体上有一个名为“电子邮件”的字段。我想确保两个实体记录的电子邮件地址应该是唯一的。为此,我编写了以下代码:

public class Class1 : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // Obtain the execution context from the service provider.
        Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
            serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

        // Get a reference to the organization service.
        IOrganizationServiceFactory factory =
        (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = factory.CreateOrganizationService(context.UserId);


        // The InputParameters collection contains all the data passed in the message request.
        if (context.InputParameters.Contains("Target") &&
            context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];

            //</snippetAccountNumberPlugin2>

            // Verify that the target entity represents an account.
            // If not, this plug-in was not registered correctly.
            if (context.MessageName.ToUpper() == "CREATE")
            {
                if (entity.LogicalName == "new_assignment1entity")
                {
                    try
                    {
                        QueryExpression query = new QueryExpression("new_assignment1entity");
                        query.ColumnSet.AddColumns("new_email");
                        EntityCollection result1 = service.RetrieveMultiple(query);
                        foreach (var a in result1.Entities)
                        {
                            int size = result1.Entities.Count;
                            if (a.Attributes["new_email"].ToString().Equals(entity["new_email"]))
                                throw new InvalidPluginExecutionException("Duplicate Email found!");
                        }
                    }
                    catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
                    {
                        //You can handle an exception here or pass it back to the calling method.
                        throw new InvalidPluginExecutionException("Some problem occurred while Querying Records!");
                    }
                }
            }
            else if (context.MessageName.ToUpper() == "UPDATE")
            {
                if (entity.LogicalName == "new_assignment1entity")
                {
                    try
                    {
                        QueryExpression query = new QueryExpression("new_assignment1entity");
                        query.ColumnSet.AddColumns("new_email");
                        EntityCollection result1 = service.RetrieveMultiple(query);
                        foreach (var a in result1.Entities)
                        {
                            int size = result1.Entities.Count;
                            if (a.Attributes["new_email"].ToString().Equals(entity["new_email"]))
                                throw new InvalidPluginExecutionException("Duplicate Email found!");
                        }
                    }
                    catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
                    {
                        //You can handle an exception here or pass it back to the calling method.
                        throw new InvalidPluginExecutionException("Some problem occurred while Querying Records!");
                    }
                }
            }
        }
    }
}

当用户使用重复的电子邮件地址创建新实体记录时,此代码有效并显示对话框打印错误消息。但是,当用户编辑现有记录(更新和现有记录)并使电子邮件地址重复时,此代码不起作用并保存了重复电子邮件地址的更新记录。
我猜测带有 UPDATE else 部分的上下文消息不起作用。
请帮帮我。

【问题讨论】:

  • 这是一个疯狂的问题,但您是否尝试过转换电子邮件地址 .ToLower() 并确保它不是区分大小写的问题..
  • @DJKRAZE 不需要转换电子邮件地址 .ToLower() 因为两个电子邮件地址完全相同。我想知道为什么执行流程没有进入 UPDATE 上下文语句。
  • 您是否附加了调试器并检查了逻辑?

标签: c# visual-studio-2010 dynamics-crm-2011


【解决方案1】:

真的不值得尝试调试它,因为不幸的是,你正在以一种非常低效的方式来解决这个问题。 (虽然最可能的原因是您查询的方式受 CRM 的“功能”影响,这意味着您没有查询您认为的所有记录)。

简而言之,您的代码说:

  • 获取new_assignment1entity 实体的所有(*) 个实例
  • 查看每条记录,直到找到一个电子邮件地址与刚刚在更新中提供的值匹配(区分大小写)的记录
  • 遇到第一个完全匹配时抛出异常(否则继续事务)

主要注意事项:

  1. QueryExpression 将只返回 CRM 中最多的前 5000 条记录
  2. 您应该过滤查询以仅返回 new_assignment1entity 属性与提供的值匹配的 new_email 记录
  3. String.Equals(string) 区分大小写,因此要真正检查重复项,您应该转换每个值的大小写
  4. 您的 size 变量没有任何作用
  5. 如果新的/更新的记录没有new_email 的值,您的代码将引发异常。您应该在尝试访问之前检查该属性是否存在

【讨论】:

  • 您对代码的分析非常有帮助,我很感激。实际上,我是 CRM Dynamics 开发的初学者,这就是我在其中学习编码技术的原因。我会尝试按照您的建议更新代码,然后将结果回复您。
  • 没问题 - 如果上面的任何项目符号不清楚,请告诉我,我可以详细说明。
【解决方案2】:

我解决了这个问题。为什么只运行创建执行流程而不运行更新的问题是我只为创建消息步骤注册了插件。为了克服这个问题,我在同一个插件中添加了一个新步骤,并使用更新消息注册它,如下图所示:

它就像魅力一样。

除此之外,@GregOwens 还提到了非常有用的几点。这些应该作为 CRM 开发的最佳实践。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多