Разработка
09
Окт
0

Постраничная обработка запроса RetrieveMultiple

По умолчанию метод RetrieveMultiple возвращает только 5000 записей. Это сделано для того, чтобы снизить нагрузку на систему и увеличить производительность. Хотя и можно увеличить это значение с помощью некоторых настроек системы, будет более правильным использовать постраничную выборку данных с помощью запроса RetrieveMultiple.

Для того чтобы задействовать постраничное возвращение данные, нужно Query Expression использовать объект PageInfo и установить для него следующие свойства:

  • PageNumber – номер страницы которую следует вернуть. Чтобы начать просмотр с самого начала, установите первое значение равным 1;
  • Count – количество записей которое следует вернуть за один запрос;
  • PagingCookie – используется для улучшения производительности при постранично возвращении записей. При первом запросе это свойство устанавливается в NULL, поскольку никаких записей еще не получено. И первый же запрос вернет Вам PagingCookie, который следует передать вместе со следующим запросом и т.д.;
  • ReturnTotalRecordCount – булево свойство, которое если установить в истину, то каждый запрос будет возвращать общее количество записей, соответствующих критериям отбора. Если установите его в ложь тогда, будет возвращаться «-1». При этом максимальное значение, которое оно вернет – 5000.

Также заметьте, что в функция обратного вызова, которая поочередно просматривает страницы, важно проверят свойство MoreRecords. Это свойство указывает, есть ли еще (на следующих страницах) записи которые можно вернуть. И оно не заменимо в том случае, если у вас более 5000 записей, поскольку TotalRecordCount в этом случаем покажет максимум 5000.

А вот целиком код, который использует постраничную обработку запроса RetrieveMultiple:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;

namespace Paging
{
    class Program
    {
        static void Main(string[] args)
        {
            // Подключаемся к CRM
            ClientCredentials credentials = new ClientCredentials();
            credentials.Windows.ClientCredential = new System.Net.NetworkCredential("Administrator", "1qaz@WSX", "D2011");
            Uri uri = new Uri("http://crm2011:5555/superfirma/XRMServices/2011/Organization.svc");
            OrganizationServiceProxy proxy = new OrganizationServiceProxy(uri, null, credentials, null);
            proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
            IOrganizationService service = (IOrganizationService)proxy;
            
            // Общие переменны
            EntityCollection retrieved;
            const int pageSize = 50; // Количество возвращаемых записей за раз
            int pageNumber = 1; // "Страница" с которой начинаем просмотр
            string pagingCookie = string.Empty;
            int totalRecordsCount = 0; // Счетчик общего кол-ва записей

            // Формируем запрос для возвращения записей
            var cols = new ColumnSet();
            cols.AddColumns(new string[] { "accountid", "name" });
            var filter = new FilterExpression { FilterOperator = LogicalOperator.And };
            filter.AddCondition(new ConditionExpression("statecode", ConditionOperator.Equal, new object[] { 0 }));
            var query = new QueryExpression
            {
                ColumnSet = cols,
                Criteria = filter,
                EntityName = "account",
                PageInfo = new PagingInfo()
                {
                    Count = pageSize
                }
            }; 
            
            do
            {
                // Задаем номер "страницы" которую нужно отобрать
                query.PageInfo.PageNumber = pageNumber;
                query.PageInfo.PagingCookie = pagingCookie;
                // query.PageInfo.ReturnTotalRecordCount = true; // Возвращает общее количество записей

                // Выполняем запрос
                retrieved = service.RetrieveMultiple(query);
                // totalRecordsCount = retrieved.TotalRecordCount; // Общее число записей

                try
                {
                    // Смотрим сколько записей было возвращено
                    if (retrieved.Entities.Count > 0)
                    {
                        totalRecordsCount += retrieved.Entities.Count;
                        Console.WriteLine("Стр " + pageNumber + ": " + retrieved.Entities.Count);

                        /* Поочередно обрабатываем данные
                        foreach (var accountEntity in retrieved.Entities)
                        {
                            if (accountEntity.Attributes.Contains("accountid"))
                            {
                                var accountId = (Guid)accountEntity.Attributes["accountid"];
                                var accountName = (string)accountEntity.Attributes["name"];
                                Console.WriteLine("Account Name: " + accountName);
                            }
                        }
                        */
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }

                // Если есть еще записи увеличиваем ращаем счетчик страниц на единицу
                if (retrieved.MoreRecords)
                {
                    pageNumber++;
                    pagingCookie = retrieved.PagingCookie;
                }
            // Если есть еще записи в системе, продолжаем выполнение
            } while (retrieved.MoreRecords);

            Console.WriteLine("Всего записей: " + totalRecordsCount);

            Console.WriteLine("\nPress <Enter> to exit.");  
            Console.ReadLine();  
        }
    }
}

Этот код делает следующее:

  • Подключается к CRM;
  • Формируем запрос для возвращения записей Организации;
  • Начинаем цикл, в котором просматриваем записи возвращаемые запросами:
    • Задаем страницу, которую хотим вернуть;
    • Выполняем запрос;
    • Просматриваем возвращенные записи;
    • Увеличиваем счетчик и запоминаем значение свойства PagingCookie;
    • Проверяем состояние свойства MoreRecords и если оно тру – повторяем цикл.

З.Ы. Заметьте, что в цикле мы вручную подсчитываем количество записей. Хотя для такого ограниченного количества, можно было воспользоваться свойством TotalRecordCount.


Комментарии (0)

*

code