Tags

, , ,

I am not expert in C#, but because C# CSOM is more more used in client applications, I had to use it. Of course, the first operation a developer is performing with CSOM is to retrieve data. There is nothing complicated in this, but CSOM cannot retrieve thousands and thousands of items at once. Imagine you want to get a list with 50.000 items and you want to populate an Excel sheet with data you obtained. It is simply not possible. But you can write the code in a way to retrieve data in chunks and execute an operation for each successfully data retrieval request.

In my case I created a class called “SharePointOperation”.

    class SharePointOperation : IDisposable
    {
        private ClientContext oContext;
        private Web oWeb;

        public SharePointOperation(string webUrl)
        {
            oContext = new ClientContext(webUrl);
            oWeb = oContext.Web;
        }

        public void Dispose()
        {
            oContext.Dispose();
        }
    }

I pass the web URL to the constructor and upon class initialization context and web are created. I have implemented IDisposable interface to be able to use my instance in a “using” statement.

The method to get list items is a simple one.

        /// <summary>
        /// Get list items
        /// </summary>
        /// <param name="listName"></param>
        /// <param name="camlQuery"></param>
        /// <param name="callback"></param>
        public void GetListItems(string listName, string camlQuery, Action<ListItemCollection> callback)
        {
            ListItemCollectionPosition position = new ListItemCollectionPosition {PagingInfo = ""};
            ListItemCollection oItems;
            List oList = oWeb.Lists.GetByTitle(listName);
 
            do
            {
                CamlQuery oQuery = new CamlQuery { ViewXml = camlQuery };
                oQuery.ListItemCollectionPosition = position;
  
                oItems = oList.GetItems(oQuery);
                oContext.Load(oItems);
                oContext.ExecuteQuery();
                callback(oItems);
                position = oItems.ListItemCollectionPosition;
            } while (position != null);       
      
           
        }

My method accepts 3 parameters: list name, CAML query string and and action which accepts “ListItemCollection” object type as parameter. Every time I get a new chunk, my action is executed.


string caml = "<View><RowLimit>10</RowLimit><Query><Where><Eq><FieldRef Name='Title' /><Value Type='Text'>Title value</Value></Eq></Where>/Query></View>";

 using (SharePointOperation op = new SharePointOperation("https://url"))
{
                op.GetListItems("List name",caml, (ListItemCollection items) =>
                {
                   // Code not extended for  brevity
                    MessageBox.Show("Done");
                });
}

I don’t pretend this code is perfect, but it might give an idea about how to organize your code and make your life easier. I do not think you want to create complicated code each time you have to deal with large lists from C# CSOM. And to be sure my message is clear, see below entire code for my class.

using System;
using Microsoft.SharePoint.Client;

    class SharePointOperation : IDisposable
    {
        private ClientContext oContext;
        private Web oWeb;

        public SharePointOperation(string webUrl)
        {
            oContext = new ClientContext(webUrl);
            oWeb = oContext.Web;
        }

        /// <summary>
        /// Get list items
        /// </summary>
        /// <param name="listName"></param>
        /// <param name="camlQuery"></param>
        /// <param name="callback"></param>
        public void GetListItems(string listName, string camlQuery, Action<ListItemCollection> callback)
        {
            ListItemCollectionPosition position = new ListItemCollectionPosition {PagingInfo = ""};
            ListItemCollection oItems;
            List oList = oWeb.Lists.GetByTitle(listName);
 
            do
            {
                CamlQuery oQuery = new CamlQuery { ViewXml = camlQuery };
                oQuery.ListItemCollectionPosition = position;
  
                oItems = oList.GetItems(oQuery);
                oContext.Load(oItems);
                oContext.ExecuteQuery();
                callback(oItems);
                position = oItems.ListItemCollectionPosition;
            } while (position != null);
         
      
           
        }

        public void Dispose()
        {
            oContext.Dispose();
        }
    }
Advertisements