web-dev-qa-db-ja.com

CRMから5000を超えるエンティティをフェッチする方法

コンソールアプリからMSDynamics CRMOnlineにクエリを実行しています。

public EntityCollection GetEntities(string entityName)
{
    IOrganizationService proxy = ServerConnection.GetOrganizationProxy();

    string request = string.Format("<fetch mapping ='logical'><entity name = '{0}'></entity></fetch>", entityName);
    FetchExpression expression = new FetchExpression(request);
    var mult = proxy.RetrieveMultiple(expression);

    return mult;
}

このコードは、mult.Entitiesで最大5000個の要素のみを返します。 CRMにはもっと多くのエンティティがあることを私は知っています。 すべてのエンティティを取得する方法は?

8
Tschareck

フェッチXMLを使用すると、一度に5000レコードしか取得できません。

より多くのレコードを取得するには、ページングCookieを使用する必要があります。ここを参照してください。

サンプル:ページングCookieでFetchXMLを使用

コードの関連ビット:

// Define the fetch attributes.
// Set the number of records per page to retrieve.
int fetchCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Specify the current paging cookie. For retrieving the first page, 
// pagingCookie should be null.
string pagingCookie = null;

サンプルはページングCookieを更新していないようであるため、メインループが変更されました。

while (true)
{
    // Build fetchXml string with the placeholders.
    string xml = CreateXml(fetchXml, pagingCookie, pageNumber, fetchCount);

     FetchExpression expression = new FetchExpression(xml);
     var results = proxy.RetrieveMultiple(expression);

    // * Build up results here *

    // Check for morerecords, if it returns 1.
    if (results.MoreRecords)
    {
        // Increment the page number to retrieve the next page.
        pageNumber++;
        pagingCookie = results.PagingCookie;
    }
    else
    {
        // If no more records in the result nodes, exit the loop.
         break;
    }
}

私は個人的にFetchXMLではなくLINQを使用する傾向がありますが、Lasse V. Karlsenが言ったことは注目に値します。この情報をユーザーに提示する場合は、おそらく何らかのページング(FetchXMLまたはLINQのいずれか)を実行する必要があります。

9
Joe

以下に示すように、LINQを使用できます。 CRM LINQプロバイダーは、クエリを自動的にページングし、完全な結果を取得するために必要な数の要求を実行し、単一のオブジェクトで完全なセットを返します。それは私たちにとって本当に便利です。ただし、注意してください。結果セットが非常に大きい場合、それは著しく遅くなり、極端な場合にはOutOfMemoryExceptionをスローすることさえあります。

 public List<Entity> GetEntities(string entityName)
    {
        OrganizationServiceContext DataContext = new OrganizationServiceContext(ServerConnection.GetOrganizationProxy());

        return DataContext.CreateQuery(entityName).toList();
    }

これは、FetchXMLを使用したページングの代替実装です。これは、公式の例よりもはるかに気に入っています。

int page = 1;
EntityCollection entityList = new EntityCollection();

do
{
    entityList = Context.RetrieveMultiple(new FetchExpression(String.Format("<fetch version='1.0' page='{1}' paging-cookie='{0}' count='1000' output-format='xml-platform' mapping='logical' distinct='false'> ... </fetch>", SecurityElement.Escape(entityList.PagingCookie), page++)));

    // Do something with the results here
}
while (entityList.MoreRecords);
6
Wedge

私も同じ問題を抱えていました。エンティティのIDをフェッチxmlまたはクエリ式に含めることで解決しました。クエリに「lead」にパスを含める場合は、「leadid」も追加します。次に、ページングCookieが自動生成されます。

0
Neo