Разработка
28
Июл
0

oData: возвращение больше 50 записей

У получения данных с помощью oData в CRM 2011 есть одно существенное ограничение: ответ может содержать максимум 50 записей (http://msdn.microsoft.com/en-us/library/gg334767.aspx). К счастью механизм работы oData’ы предоставляет возможность организовать «постраничную» выборку данных, чтобы иметь возможность в конечном итоге получить полный набор данных. Для этого каждый oData-ответ снабжен специальным атрибутом ( __next) – маркером разбивки на страницы, который содержит готовый URL для запроса следующей «страницы» данных. Пример такого URL:

http://crmdev01:5555/ContosoCRM/xrmservices/2011/OrganizationData.svc/AccountSet?$skiptoken=1,'accountid','%7BFBF7BBA7-9368-E111-912C-0800275F9129%7D','%7B085B65E4-9268-E111-912C-0800275F9129%7D'

Обратите внимание на параметр $skiptoke, который указывает на необходимость разбивки на страницы.

Однако и тут не обошлось без ложки дёгтя: если Вы будете использовать команду $expand, чтобы возвратить связанные записи объекта в результатах запроса, то больше 50 связанных записей Вы все равно не вернете, поскольку наборы дополнительных данных не содержат маркеров разбивки на страницы.

Чтобы выполнить такой запрос с постраничной разбивкой и «складированием» данных в одном общем массиве, можете использовать такой код:

function onLoad() {
    // Объявляем общий массив
    accounts = new Array();
    // Выполняем первый запрос
    getAccount(Xrm.Page.context.getServerUrl() + '/xrmservices/2011/OrganizationData.svc/AccountSet?$select=Name');
    
    alert(accounts.length);
}

function getAccount(serverURL) {
    var getAcc = new XMLHttpRequest();
    getAcc.open("GET", serverURL, false);
    getAcc.setRequestHeader("Accept", "application/json");
    getAcc.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    getAcc.onreadystatechange = function () {
        if (this.readyState == 4) {
            if (this.status == 200) {
                // Получаем результат запроса
                var Accs = JSON.parse(this.responseText).d;
                // Присоединяем результат к общему массиву
                accounts = accounts.concat(Accs.results);
                // Если есть маркер разбивки на страницы, то повторяем запрос
                if (Accs.__next) getAccount(Accs.__next);
            } else {
                alert("Не получилось. Сори.");
            }
        }
    };
    getAcc.send(null);
}

Тут мы делаем следующие вещи:

  • Объявляем глобальный массив, в который будем суммировать получаемые частичные результаты запросов;
  • Выполняем первичный запрос и его результаты добавляем в глобальный массив;
  • Из параметра __next вытаскиваем и отправляем следующий запрос;
  • И так до тех пор пока не закончатся запросы…


Черный ход

Радикальным способом решения проблемы является увеличение предела в 50 записей. Этот параметр хранится в БД MSCRM_Config, называется MaxResultsPerCollection и расположен в таблице ServerSettings.

Данный параметр может быть изменен либо программно, либо через PowerShell. Писать прогу мне лень, поэтому воспользуемся PowerShell’ом. В данном случае увеличим максимальный размер возвращаемых записей до 75. Запустите PowerShell и выполните такой код:

Add-PSSnapin Microsoft.Crm.PowerShell
$setting = New-Object "Microsoft.Xrm.Sdk.Deployment.ConfigurationEntity"
$setting.LogicalName = "ServerSettings"
$setting.Attributes = New-Object "Microsoft.Xrm.Sdk.Deployment.AttributeCollection"
$attribute = New-Object "System.Collections.Generic.KeyValuePair[String, Object]" ("MaxResultsPerCollection", 75)
$setting.Attributes.Add($attribute)
Set-CrmAdvancedSetting -Entity $setting

Чтобы проверить изменилось ли значение, выполните в БД такой запрос:

SELECT
	ColumnName,
	IntColumn
FROM
	MSCRM_CONFIG.dbo.ServerSettingsProperties
WHERE
	ColumnName = 'MaxResultsPerCollection'


Примечание:

  • Т.к. эти значения кэшируются, то выполните IISRESET, чтобы CRM наверняка «узнал» об изменениях;
  • Заметьте, что увеличение максимального количества возвращаемых записей, может негативным образом сказаться на производительности.
Комментарии (0)

*

code