IOrganisationService.Извлекаемая запись не существует

#c# #dynamics-crm #dynamics-crm-2013

#c# #динамика-crm #динамика-crm-2013

Вопрос:

Я создал код, чтобы проверить, существует ли запись в CRM. Проблема в том, что IOrganisationService.Retrieve возвращает ошибку вместо null, если запись не найдена. Я ожидаю, что несколько записей не будут найдены, и я не хочу использовать try catch, а затем использовать ошибку из catch.

 using (OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, HomeRealmUri, credentials, null))
            {
                IOrganizationService service = (IOrganizationService)serviceProxy;
                //Get record

                var record = service.Retrieve(entryId, guid, new ColumnSet(true)); //switch to var if no work
                //Check if record is not null/empty
                recordExists = !String.IsNullOrWhiteSpace(record.Id.ToString()); //<- does the record exist
            }
  

Предложения?

Комментарии:

1. Почему вы не хотите использовать try / catch ? Смотрите Мой ответ для получения справки.

Ответ №1:

Метод Retrieve предполагает, что запись с заданным идентификатором действительно существует в системе. В общем, это не удается только в двух сценариях:

  1. Запись была удалена другим пользователем или процессом.
  2. У пользователя недостаточно прав на чтение.

Когда вам нужно запросить данные, которые могут не существовать, или когда запрос может выдать ноль, одну или несколько записей, используйте QueryExpression запросы; вы можете выдавать эти запросы с помощью RetrieveMultiple метода. Если хотите, вы также можете использовать LINQ для CRM, который в основном оборачивает QueryExpression функциональность.

Ответ №2:

Используется RetrieveMultiple для извлечения пользователей с интересующим вас идентификатором:

 // Create and cache the plugin context
this.context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
this.service = serviceFactory.CreateOrganizationService(this.context.UserId);

// Retrieve users with certain ID
Guid userId = Guid.NewGuid();
var query = new QueryExpression("systemuser");
query.Criteria.AddCondition(new ConditionExpression("systemuserid", ConditionOperator.Equal, userId));

EntityCollection users;
try
{
    users = this.service.RetrieveMultiple(query);
}
catch (FaultException<OrganizationServiceFault> faultException)
{
    throw new InvalidPluginExecutionException($"Failed to retrieve system users that have an ID of '{userId}'", faultException);
}

if (users.Entities.Length == 0) // (or !users.Entities.Any() using Linq)
{
    // Do something
}
  

Комментарии:

1. Код работает, возможно, мое объяснение было немного плохим. Метод извлечения выдает ошибки, если результат не найден; Я хочу знать, какие записи CRM не существуют, без необходимости использовать catch, чтобы сказать, что запись не существует.

2. Я не думаю, что это возможно с помощью этого Retrieve метода. Служба CRM выдаст исключение типа FaultException<OrganizationServiceFault> , если запись не существует. Однако вы могли бы использовать RetrieveMultiple для извлечения списка записей с интересующим вас идентификатором — если длина равна 0, исключение не будет выдано. Я обновил свой ответ.

3. Предполагается, Retrieve что метод возвращает указанную запись, и вызов ее завершится неудачно только в редких случаях. Следовательно, обработка ошибок предпочтительно должна выполняться на максимально возможном уровне.

4. @Phil Спасибо за помощь, ваше решение сработало для меня.