Я пишу плагин CRM. Он должен запускаться по сообщению RetrieveMultiple для объекта продавца на этапе 20 (перед операцией).
Проблема в том, что мне нужен список всех существующих продавцов на этом самом предоперационном этапе (чтобы сравнить список со списком удаленных заказов и при необходимости создать новые заказы).
Чтобы получить список всех заказов, наивный подход заключается в использовании service.retrieveMultiple(salesOrderQuery), где salesOrderQuery - это QueryExpression в salesorder.
Это, конечно, заставляет процесс Dynamics 365 зайти в бесконечный цикл.
У меня вопрос: как я могу «предварительно получить» всех продавцов на этапе подготовки к операции для сообщения «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);
}
}
}





Обычно сообщение RetrieveMultiple будет вызываться во всех местах, таких как поиск Adv, просмотры, поиск, вызовы service.RetrieveMultiple, где система запрашивает эту конкретную сущность.
Используйте свойство контекста Depth для избегать бесконечных циклов.
if (context.Depth > 1)
return;
Теперь код работает нормально при проверке
if (context.Depth > 1). Но при отладке я заметил, что строкаEntityCollection entities = service.RetrieveMultiple(soQuery);всегда вызывает исключение, не обрабатываемое пользователем. Я не понимаю, почему не удается получить объекты при отладке. Прекрасно работает при работе без профилирования в динамике.