【问题标题】:RetrieveMultiple within a RetrieveMultiple call (causes infinite loop)RetrieveMultiple 调用中的 RetrieveMultiple(导致无限循环)
【发布时间】:2018-06-06 08:59:29
【问题描述】:

我正在编写一个 CRM 插件。它应该在第 20 阶段(预操作)的 salesorder 实体的“RetrieveMultiple”消息上触发。

问题是我需要一个在那个非常预操作阶段的所有现有销售订单的列表(以便将该列表与远程订单列表进行比较并在需要时创建新订单)。

要获取所有订单的列表,最简单的方法是使用service.retrieveMultiple(salesOrderQuery),其中salesOrderQuery 是salesorder 上的QueryExpression。

这当然会导致动态 365 进程进入无限循环。

我的问题是:如何在预操作阶段“预检索”所有 salesorder 以获取 salesorder 上的“RetrieveMultiple”消息而不会导致无限循环?

我目前正在考虑也许我应该更改导致我的插件执行的事件。我的目标是在用户加载“订单”页面时从远程系统获取所有新创建的订单。到目前为止,我发现的唯一方法是在“RetrieveMultiple”消息上注册我的插件步骤。

那么如何获取所有现有订单呢?

到目前为止,我的插件如下所示:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSPlugins
{
    public class RetrieveOrdersPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            var context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;

            // check if pre-operation
            if (context.Stage != 20)
                throw new InvalidPluginExecutionException("Must run as pre-operation stage 20");
            if (context.MessageName != "RetrieveMultiple")
                throw new InvalidPluginExecutionException("Registered for " + context.MessageName + " only RetrieveMultiple is supported");
            if (context.PrimaryEntityName != "salesorder")
                throw new InvalidPluginExecutionException("Registered for " + context.PrimaryEntityName + " entity and only salesorder is supported");

            var tracingService = serviceProvider.GetService(typeof(ITracingService)) as ITracingService;
            var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
            var service = serviceFactory.CreateOrganizationService(context.UserId) as IOrganizationService;

            tracingService.Trace("Plug-in RetrieveOrders executed");

            QueryExpression soQuery = new QueryExpression();
            soQuery.EntityName = "salesorder";
            soQuery.ColumnSet = new ColumnSet() { AllColumns = true };

            soQuery.Criteria = new FilterExpression();
            soQuery.Criteria.FilterOperator = LogicalOperator.And;

            // The following line causes an infinite loop...
            EntityCollection entities = service.RetrieveMultiple(soQuery);

        }
    }
}

【问题讨论】:

    标签: c# dynamics-crm infinite-loop


    【解决方案1】:

    基本上,RetrieveMultiple 消息将在所有地方调用,例如 Adv find、views、lookup、service.RetrieveMultiple 调用,系统正在查询该特定实体。

    将上下文的Depth 属性用于avoid infinite loops

    if (context.Depth > 1)
        return;
    

    【讨论】:

    • 代码现在在检查if (context.Depth > 1) 时运行良好。但是在调试时,我发现EntityCollection entities = service.RetrieveMultiple(soQuery); 行总是会导致用户未处理的异常。我不明白为什么在调试时检索实体失败。在没有动态分析的情况下运行时效果很好。
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 2021-06-12
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多