[CRM] Как получить все данные, если CRM 2011 имеет лимит 5000 записей на ответ

Приходится работать с все большим объемом данных, столкнулся с тем, что CRM имеет ограничение на получение данных через Fetch-запросы. 5000 записей. Многие наверное замечали, к примеру, что на гридах сущностей CRM, имеющих больше 5000 записей в поле количество под гридом обычно указано просто 5000+.

Для того чтобы избавиться от этого ограничение можно просто установить в реестре ключ, который убирает этот лимит, делается это довольно просто и описание можно найти в интернете, к примеру здесь:

  1. Click Start, click Run, type regedit in the Open box, and then click OK.
  2. Locate and then select the following registry subkey:HKEY_LOCAL_MACHINE\Software\Microsoft\MSCRM
  3. On the Edit menu, point to New, and then click DWORD Value.
    image
  4. Type TurnOffFetchThrottling, and then press ENTER.
    image
  5. Right-click TurnOffFetchThrottling, and then click Modify.
    image
  6. Type a number other than 0 in the Value data box, and then click OK.
    imageimage
    Note Step 6 lets you retrieve the number of records specified in the Count attribute of your fetch statement.
  7. On the File menu, click Exit.
    image

Но это не правильный подход, т.к, во первых такое решение тормозит работу, во вторых не гарантирует что Вы таки получите все результаты.

А теперь по порядку — как стоит решать эту задачу:

1. В fetch запросу можно указывать «страницу» данных, которую Вы хотите получить:

<fetch mapping='logical' version='1.0' page='1'>
<entity name='EntityName'>
<attribute name='AttributeName'/>
</entity>
</fetch>

* This source code was highlighted with Source Code Highlighter.

2. Возникает другой вопрос, а как узнать что мы получили все данные?
Очень просто. Для начала надо понимать, что когда мы выполняет запрос:

var query = new FetchExpression(fetch);
var tempResult = service.RetrieveMultiple(query);

* This source code was highlighted with Source Code Highlighter.

В ответ от CRM приходит нечто вроде:

<resultset morerecords='0' paging-cookie='&#60;cookie page="1"><listmemberid last="{E1B03485-0000-0000-0000-00155D107003}" first="{A74C877A-0000-0000-0000-00155D107003}" /></cookie>'>
<result>
<listmemberid>{A712877A-0000-1231-0000-00435D107003}</listmemberid>
<listid.listname>List 1</listid.listname>
<entityid.fullname>Dmitry Pelevin</entityid.fullname>
<entityid.emailaddress1>d@pel.ru</entityid.emailaddress1>
</result>
<result>
<listmemberid>{A943377A-0000-1231-0000-001554407003}</listmemberid>
<listid.listname>List 2</listid.listname>
<entityid.fullname>Ivan Konstantinov</entityid.fullname>
<entityid.emailaddress1>ikon@test.ru</entityid.emailaddress1>
</result>
</resultset>

* This source code was highlighted with Source Code Highlighter.

Очевидно, что волшебный параметр morerecords=’0′ не случаен.

А чтобы получить его значение в C# нужно просто заглянуть сюда:

tempResult.MoreRecords

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

private static List<Entity> GetAllExemplarsOfEntity(string entityName, List<string> attributes, IOrganizationService service)
{
int i = 1;
bool bFinished = false;
var allData = new List<Entity>();
while (bFinished == false)
{
StringBuilder sbFetch = new StringBuilder();
sbFetch.AppendFormat("<fetch mapping='logical' version='1.0' page='{0}'>", i);
sbFetch.AppendFormat("<entity name='{0}'>", entityName);
foreach (var attr in attributes)
{
sbFetch.AppendFormat("<attribute name='{0}'/>", attr);
}
sbFetch.Append("</entity>");
sbFetch.Append("</fetch>");
var query = new FetchExpression(sbFetch.ToString());
var tempResult = service.RetrieveMultiple(query);

allData.AddRange(tempResult.Entities.ToList());

if (tempResult.MoreRecords)
i++;
else
bFinished = true;
}
return allData;
}

Если Вы нашли ошибку, пожалуйcта выделите ее и нажмите Shift + E или нажмите здесь чтобы информировать меня. Спасибо.

Добавить комментарий