Получить общее количество совокупных записей, если записи содержат более 50000 записей

#c# #dynamics-crm #crm #dynamics-crm-2015

#c# #dynamics-crm #crm #dynamics-crm-2015

Вопрос:

У нас огромное количество записей в нашем объекте CRM. Я пытаюсь получить общее количество записей с помощью aggregate count в fetch xml. Но у него есть ограничение в 50000 записей. Я думаю, что есть способ изменить этот параметр в локальной CRM. Но я не хочу это менять.

Ранее мы использовали метод разбивки на страницы для получения общего количества (5000 каждый раз). Но это занимает много времени

 public static int GetTotalRowCount(string fetchXml)
{
  try
  {
    using (OrganizationServiceContext svcContext = new OrganizationServiceContext(ServerConnection.CrmService))
    {
      int totalCount = 0;
      int fetchCount = 5000;
      int pageNumber = 1;
      string pagingCookie = null;
      string xml = string.Empty;
      RetrieveMultipleRequest fetchRequest1 = null;
      EntityCollection entityCollection = null;

      xml = CreateXml(fetchXml, pagingCookie, pageNumber, fetchCount);
      fetchRequest1 = new RetrieveMultipleRequest
      {
        Query = new FetchExpression(xml)
      };

      entityCollection = ((RetrieveMultipleResponse)svcContext.Execute(fetchRequest1)).EntityCollection;

      while (entityCollection.MoreRecords)
      {
        //moving to next page
        pageNumber  ;

        xml = CreateXml(fetchXml, pagingCookie, pageNumber, fetchCount);
        fetchRequest1 = new RetrieveMultipleRequest
        {
          Query = new FetchExpression(xml)
        };

        entityCollection = ((RetrieveMultipleResponse)svcContext.Execute(fetchRequest1)).EntityCollection;
        totalCount = totalCount   entityCollection.Entities.Count;
      }

      return totalCount;
    }
  }
  catch (Exception ex)
  {
  }
}
  

но это занимает много времени. Следовательно, я изменил его на метод совокупного подсчета —
Изменен Fetchxml следующим образом —

 <fetch mapping='logical' output-format='xml-platform' no-lock='true' distinct='false' aggregate='true'>
  <entity name='abc_data'>
    <attribute name='abc_id' aggregate='count' alias='count'/>.....
  

код, подобный этому

  int Count = 0;
 FetchExpression fetch = new FetchExpression(fetchXml);
 EntityCollection result = ServerConnection.CrmService.RetrieveMultiple(fetch);
 if (result.Entities.Count > 0)
 {
     Entity entity = result.Entities[0];
     AliasedValue value = (AliasedValue)entity["count"];
     Count = (int)value.Value;
  }
  return Count ;
  

Теперь здесь это выдает исключение, если записей больше 50000.

Итак, есть ли способ извлекать 50000 записей за раз с помощью aggregate count и перебирать их для получения общего количества?

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

1. Смотрите раздел ПРЕВЫШЕН ЛИМИТ ЗАПИСИ ПО ЗАПРОСУ AGGREGATE — Изменение локальных настроек и используйте расширенные параметры конфигурации , чтобы узнать, как это изменить для вашей локальной системы.

2. @omkar, Год назад я работал с «Решением Dynabacus» для D365, в котором оно возвращает общее количество записей (без каких-либо ограничений) выбранных объектов, я пытался найти это решение для вас, но безуспешно, издатель, возможно, удалил это решение со своего сайта.

Ответ №1:

Ограничения на агрегацию FetchXML — это проблема, с которой мы все сталкиваемся. Я хотел решить проблему раз и навсегда, поэтому я создал онлайн-инструмент под названием AggX для запуска агрегатов для любого количества строк. В настоящее время он бесплатен для использования.

Вы можете проверить это на https://aggx.meta.tools и, пожалуйста, обратите внимание, что это работает только с Dynamics 365 Online. Также, пожалуйста, обратите внимание, что если у вас есть большое количество строк, выполнение которых займет более 5 минут, вам следует отслеживать AggX, чтобы избежать автоматического выхода из системы после нескольких минут простоя.

Если ваша система запущена или вы хотите написать свой собственный код для выполнения сводных данных, вы можете разработать алгоритм для разделения данных на блоки менее чем по 50 000 строк. Затем вы можете запустить агрегат FetchXML для каждого фрагмента и суммировать результаты. Вот как работает движок AggX.

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

1. Да, я пытался это сделать .. изменил мой fetchxml следующим образом — <fetch mapping=»logical» output-format = «xml-platform» no-lock = «true» distinct = «false» aggregate =»true» page = «1» count = «50000»> .. так что я могу извлекать фрагмент из 50000 за раз.. но все равно он возвращает более 50000

2. FetchXML жестко запрограммирован так, чтобы останавливаться на 5000 независимо от установленного нами размера страницы. Вы должны разбивать данные на части на основе самих данных, например «имя начинается с ‘A'», затем «имя начинается с ‘B'» и так далее. Или «создано в январе», затем создано в феврале» и так далее.

3. Эти предлагаемые решения для профессионального продукта абсолютно нестандартны. За что именно мы платим?

Ответ №2:

Если вы просто хотите подсчитать

https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/reference/retrievetotalrecordcount?view=dataverse-latest

                 string[] entitylist = new string[] { };
                Array.Resize(ref entitylist, entitylist.Length   1);
                entitylist[entitylist.Length - 1] = "someentityname";
                RetrieveTotalRecordCountRequest req = new RetrieveTotalRecordCountRequest
                {
                    EntityNames = entitylist
                };
                EntityRecordCountCollection m = ((RetrieveTotalRecordCountResponse)OrganizationService.Execute(req)).EntityRecordCountCollection;
                long count = 0;
                foreach (var i in m)
                {
                    Console.WriteLine(i.Key   " ="   i.Value);
                    count  = i.Value;
                }
                Console.WriteLine($"Count ={count}");