Export (0) Print
Expand All

Using the Paging Cookie (PageInfo)

banner art

[Applies to: Microsoft Dynamics CRM 4.0]

The paging cookie is a performance feature that makes paging in the application faster for very large datasets. It is available in both Fetch and QueryExpression queries. When you query for a set of records, the result will contain a value for the paging cookie. For better performance, you can pass that value when you retrieve the next set of records.

Fetch and QueryExpression use a different format for their paging cookies. If you convert from one query format to the other by using the FetchXmlToQueryExpression message or the QueryExpressionToFetchXml message, the paging cookie value will be ignored.

In addition, if you request nonconsecutive pages, the paging cookie value will be ignored.

When you use the paging cookie with FetchXML, make sure that you use the correct encoding as shown in the following example:

strQueryXML = "<fetch mapping='logical' paging-cookie='&lt;cookie page=&quot;1&quot;&gt;&lt;accountid last=&quot;{E062B974-7F8D-DC11-9048-0003FF27AC3B}&quot; first=&quot;{60B934EF-798D-DC11-9048-0003FF27AC3B}&quot;/&gt;&lt;/cookie&gt;' page='2' count='2'><entity name='account'><all-attributes/></entity></fetch>";

Example

The following sample code shows how to use the paging cookie with Query Expression.

[C#]
// Set up the CRM Service.
CrmService service = CrmServiceUtility.GetCrmService(crmServerUrl, orgName);
// Cache credentials so each request does not have to be re-authenticated.
service.PreAuthenticate = true;

// Define the fetch attributes.
// The number of records per page to retrieve.
int fetchCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Initialize the number of records.
int recordCount = 0;

// The parent account Id would typically be required in case you intend 
// to filter the number of account records by associated parent account.
parentAccountId = new Guid("{832CF447-4E70-45db-A6BE-14F1AB343076}");

// Create the query expression
QueryExpression query = new QueryExpression();
query.EntityName = EntityName.account.ToString();

// Define the condition expressions for retrieving records.
// Retrieve only active records.
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "statecode";
condition1.Operator = ConditionOperator.Equal;
condition1.Values = new string[] { AccountState.Active.ToString() };

// Retrieve records that are associated with the parent accounts.
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "parentaccountid";
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new string[] { parentAccountId.ToString() };

// Define the filter expression to include recently defined conditions.
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.And;
filter.Conditions = new ConditionExpression[] { condition1, condition2 };

// Add the filter expression to the query expression.
query.Criteria = filter;

// Define columns to retrieve from the query.
ColumnSet cols = new ColumnSet();
cols.Attributes = new string[] { "name", "emailaddress1", "accountid" };

// Set the columnset property of the query with the recently defined columns.
query.ColumnSet = cols;

// Define the order expression to retrieve the records.
OrderExpression order = new OrderExpression();
order.AttributeName = "name";
order.OrderType = OrderType.Ascending;

// Add the order experssion to the query expression.
query.Orders = new OrderExpression[] { order };

// Assign the pageinfo properties to the query expression.
query.PageInfo = new PagingInfo();
query.PageInfo.Count = fetchCount;
query.PageInfo.PageNumber = pageNumber;
// The current paging cookie. For retrieving the first page, 
// pagingCookie should be null.
query.PageInfo.PagingCookie = null;

Console.WriteLine("#\tAccount Name\t\t\tEmail Address");

while (true)
{
    // Retrieve the page.
    BusinessEntityCollection results = service.RetrieveMultiple(query);

    if (results.BusinessEntities != null)
    { 
        // Retrieve all records from the result set.
        foreach (account acct in results.BusinessEntities)
        {
            Console.WriteLine(
           "{0}.\t{1}\t\t{2}",
           ++recordCount,
           acct.name,
           acct.emailaddress1);
        }
    }

    // Check for morerecords, if it returns true.
    if (results.MoreRecords)
    {
        // Increment the page number to retrieve the next page.
        query.PageInfo.PageNumber++;
        // Set the paging cookie to the paging cookie returned from current results.
        query.PageInfo.PagingCookie = results.PagingCookie;
    }
    else
    {
        // If no more records are in the result nodes, exit the loop.
        break;
    }
}

Example

The following sample code shows how to use the paging cookie with Fetch.

// Set up the CRM Service.
CrmService service = CrmServiceUtility.GetCrmService(crmServerUrl, orgName);
// Cache credentials so each request does not have to be re-authenticated.
service.PreAuthenticate = true;

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

// The parent account Id would typically be required in case you intend 
// to filter the number of account records by associated parent account.
parentAccountId = new Guid("{832CF447-4E70-45db-A6BE-14F1AB343076}");

// Create the FetchXml string for retrieving all child accounts to a parent account.
// This fetch query is using 1 placeholder to specify the parent account id 
// for filtering out required accounts. Filter query is optional.
// Fetch query also includes optional order criteria, which, in this case, is used 
// to order the results in ascending order on the name data column.
string fetchXml = string.Format(@"<fetch version='1.0' 
    mapping='logical' 
    output-format='xml-platform'>
    <entity name='account'>
        <attribute name='name' />
        <attribute name='emailaddress1' />
        <order attribute='name' descending='false'/>
        <filter type='and'>
                        <condition attribute='parentaccountid' 
operator='eq' value='{0}' uiname='' uitype='' />
        </filter>
    </entity>
</fetch>",
parentAccountId);

Console.WriteLine("#\tAccount Name\t\t\tEmail Address");

while (true)
{
    // Build fetchXml string with the placeholders.
    string xml = CreateXml(fetchXml, pagingCookie, pageNumber, fetchCount);
    
    // Excute the fetch query and get the xml result.
    string fetchResult = service.Fetch(xml);

    // Load the fetch result into XMLDocument to parse its cotents.
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(fetchResult);

    // The morerecords attribute will return 1 if there are more records.
    string moreRecords = ExtractAttribute(doc, "morerecords");

    // The paging-cookie attribute holds the paging cookie to pass in the next query.
    pagingCookie = ExtractAttribute(doc, "paging-cookie");

    // Retrieve the result nodes.
    XmlNodeList resultNodes = doc.DocumentElement.SelectNodes("result");

    // Retrieve all records from the result set.
    foreach (XmlNode resultNode in resultNodes)
    {   
        Console.WriteLine(
           "{0}.\t{1}\t\t{2}",
           ++recordCount,
           ExtractNodeValue(resultNode, "name"),
           ExtractNodeValue(resultNode, "emailaddress1"));
    }

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

        static string ExtractNodeValue(XmlNode parentNode, string name)
        {
            XmlNode childNode = parentNode.SelectSingleNode(name);

            if (null == childNode)
            {
                return null;
            }
            return childNode.InnerText;
        }

        static string ExtractAttribute(XmlDocument doc, string name)
        {
            XmlAttributeCollection attrs = doc.DocumentElement.Attributes;
            XmlAttribute attr = (XmlAttribute)attrs.GetNamedItem(name);
            if (null == attr)
            {
                return null;
            }
            return attr.Value;
        }

        static string CreateXml(string xml, string cookie, int page, int count)
        {
            StringReader stringReader = new StringReader(xml);
            XmlTextReader reader = new XmlTextReader(stringReader);

            // Load document
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);

            return CreateXml(doc, cookie, page, count);
        }

        static string CreateXml(XmlDocument doc, string cookie, int page, int count)
        {
            XmlAttributeCollection attrs = doc.DocumentElement.Attributes;

            if (cookie != null)
            {
                XmlAttribute pagingAttr = doc.CreateAttribute("paging-cookie");
                pagingAttr.Value = cookie;
                attrs.Append(pagingAttr);
            }

            XmlAttribute pageAttr = doc.CreateAttribute("page");
            pageAttr.Value = System.Convert.ToString(page);
            attrs.Append(pageAttr);

            XmlAttribute countAttr = doc.CreateAttribute("count");
            countAttr.Value = System.Convert.ToString(count);
            attrs.Append(countAttr);

            StringBuilder sb = new StringBuilder(1024);
            StringWriter stringWriter = new StringWriter(sb);

            XmlTextWriter writer = new XmlTextWriter(stringWriter);
            doc.WriteTo(writer);
            writer.Close();

            return sb.ToString();
        }

    }

See Also

Concepts

Reference

Other Resources


© 2010 Microsoft Corporation. All rights reserved.


Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft