0

I'm trying to retrieve all lists from my online tenant from Visual Studio. After much fumbling and unsuccessful attempts with:

ListItemCollection listItemCollection = oList.GetItems(query);

and

context.Load(listItemCollection, items => items.IncludeWithDefaultProperties(item => item.DisplayName));

I arrived at this (feel free to criticize, it's all welcome):

            ClientContext context = new ClientContext(url);
            context.Credentials = new SharePointOnlineCredentials(userName, password);

            Web site = context.Web;
            context.Load(context.Web.Webs);
            context.ExecuteQuery();

            for (int i = 0; i < site.Webs.Count; i++)
            {
                context.Load(site.Webs[i].Lists);
            }
            context.ExecuteQuery();

            string lists = "";
            for (int i = 0; i < site.Webs.Count; i++)
            {

                lists = lists + context.Web.Webs[i].Url + "\n";
                for (int j = 0; j < context.Web.Webs[i].Lists.Count; j++)
                {
                    lists = lists + context.Web.Webs[i].Lists[j].Title + " " + context.Web.Webs[i].Lists[j].Created + " " + context.Web.Webs[i].Lists[j].ItemCount + "\n";
                }

                lists = lists + "\n\n\n";
            }

            Console.WriteLine(lists);


            context.Dispose();

Is it correct to use context.Load() in a loop? If I don't load all the lists beforehand the for loop gives me "uninitialized error".
Is it correct to use context.ExecuteQuery() multiple times? Which direction should I be going? Considering that it needs to authenticate/server load/application speed, should I use smaller and often queries or should I rather try to gather more .Load() and run it in single .ExecuteQuery()?

1 Answer 1

2

Since CSOM supports Request Batching that allows to minimize the number of messages that are passed between the client and the server, it matters how operations are submitted to the server using ClientContext.ExecuteQuery method:

  • ClientContext.ExecuteQuery method performs the actual request to the server, it could contain single or multiple operations. So, the best practise is to minimize the number of calls using ClientContext.ExecuteQuery method.
  • You could use the ClientContext.Load method as many times as needed since it only tells the client context object what to return when it executes a batched request.

Further steps for optimization

Instead of:

Web site = context.Web;
context.Load(context.Web.Webs);
context.ExecuteQuery();

for (int i = 0; i < site.Webs.Count; i++)
{
     context.Load(site.Webs[i].Lists);
}
context.ExecuteQuery();

you could use the following way of loading Lists for a sub Webs:

context.Load(context.Web.Webs,wc => wc.Include(w => w.Url, w => w.Lists));
context.ExecuteQuery();

So, instead of retrieving sub webs and lists in a separate requests, you could combine both operations to perform a single request.

2
  • Thank you Vadim, you are helping me once again. Let me test and I'll get back to you.
    – grisha
    Jul 3, 2014 at 11:01
  • Great, hope this helped you Jul 3, 2014 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.