Saturday 22 June 2019

How To Retrieve More than 5000 records in D365 Console App

As you might already know that, by default, only 5000 records are retrieved irrespective of whether you are using an Advanced Find or server side code, hence it is very important especially in case if you are developing an enterprise application, you should ensure that the result set that you are acting on should hold the complete results and not the default 5000.

Below class can be used to achieve the same.
The key thing to notice here is, we are basically using the pagingCookie, MoreRecords & pageNumber properties to achieve this.

HelperClass:

class RetrieveAllRecords
    {
        #region Retrieve more than 5000 records
        /// <summary>
        /// Retrieve more than 5000 records based on pagig cookie information
        /// </summary>
        /// <param name="service">Organization service</param>
        /// <param name="fetchXml">Fetchml describing the filter criteria</param>
        /// <returns></returns>
        public static List<Entity> RetreiveAll(IOrganizationService service, string fetchXml)
        {
            // Set the number of records per page to retrieve.
            int fetchCount = 5000;
            // Initialize the page number.
            int pageNumber = 1;

            // Specify the current paging cookie. For retrieving the first page,
            // pagingCookie should be null.
            string pagingCookie = null;
            List<Entity> entityCollection = new List<Entity>();

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

                // Excute the fetch query and get the xml result.
                RetrieveMultipleRequest fetchRequest = new RetrieveMultipleRequest
                {
                    Query = new FetchExpression(xml)
                };
                EntityCollection returnCollection = ((RetrieveMultipleResponse)service.Execute(fetchRequest)).EntityCollection;
                foreach (var entity in returnCollection.Entities)
                {
                    entityCollection.Add(entity);
                }

                // Check for morerecords, if it returns 1.
                if (returnCollection.MoreRecords)
                {
                    pageNumber++;
                    pagingCookie = returnCollection.PagingCookie;
                }
                else
                {
                    return entityCollection;
                }
            }
        }
        #endregion

        #region CreateXml
        /// <summary>
        /// Creates and fomrats xml based on the paging cookie
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="cookie"></param>
        /// <param name="page"></param>
        /// <param name="count"></param>
        /// <returns>FetchXML</returns>
        public 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);
        }
        #endregion

        #region CreateXml Document
        /// <summary>
        /// Creates a XML Document that can be sent back to CRM along with Paging Information
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="cookie"></param>
        /// <param name="page"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string CreateXml(XmlDocument doc, string cookie, int page, int count)
        {
            XmlAttributeCollection attributes = doc.DocumentElement.Attributes;
            if (cookie != null)
            {
                XmlAttribute pagingAttribute = doc.CreateAttribute("paging-cookie");
                pagingAttribute.Value = cookie;
                attributes.Append(pagingAttribute);
            }
            XmlAttribute pageAttribute = doc.CreateAttribute("page");
            pageAttribute.Value = System.Convert.ToString(page);
            attributes.Append(pageAttribute);
            XmlAttribute countAttribute = doc.CreateAttribute("count");
            countAttribute.Value = System.Convert.ToString(count);
            attributes.Append(countAttribute);
            StringBuilder stringBuilder = new StringBuilder(1024);
            StringWriter stringWriter = new StringWriter(stringBuilder);
            XmlTextWriter writer = new XmlTextWriter(stringWriter);
            doc.WriteTo(writer);
            writer.Close();
            return stringBuilder.ToString();
        }
        #endregion
    }

No comments:

Post a Comment