3

I have a WPF application I've built that relies on data within a SharePoint list (synced from a website). I believe, perhaps incorrectly that this query will be limited to retrieving 100 rows at a time.

Is there a way to batch my requests so I can fetch more than 100 rows in the one query?

private static ListItemCollection LoadListItemCollection(string status)
{
    using (var ctx = new ClientContext("http://sharepoint/resources"))
    {
        var list = ctx.Web.Lists.GetByTitle("Resource Orders");


        var query = new CamlQuery
                        {
            ViewXml = @"<View><Query><Where><Eq><FieldRef Name=""Status""></FieldRef><Value Type=""Text"">Approved</Value></Eq></Where></Query></View>"
        };

        switch (status)
        {

            case "Ordered":
                query.ViewXml =
                    @"<View><Query><Where><Eq><FieldRef Name=""Status""></FieldRef><Value Type=""Text"">Ordered</Value></Eq></Where></Query></View>";
                break;

            case "History":
                query.ViewXml =
                    @"<View><Query><Where><In><FieldRef Name=""Status""/><Values><Value Type=""Text"" >Rejected</Value><Value Type=""Text"">Dispatched</Value><Value Type=""Text"">Ordered</Value><Value Type=""Text"">Approved</Value></Values></In></Where></Query></View>";
                break;

            case "Approved":
            default:
                query.ViewXml =
                    @"<View><Query><Where><Eq><FieldRef Name=""Status""></FieldRef><Value Type=""Text"">Approved</Value></Eq></Where></Query></View>";
                break;
        }

        var collListItem = list.GetItems(query);

        ctx.Load(
            collListItem,
            items =>
            items.Include(
                item => item.Id,
                item => item.DisplayName,
                item => item.HasUniqueRoleAssignments,
                item => item["Status"] ,
                item => item["Persona"],
                item => item["Quantity_x0020_Ordered"],
                item => item["Resource_x0020_Name"],
                item => item["Title"],
                item => item["Customer_x0020_E_x002d_mail"],
                item => item["Customer_x0020_Phone_x0020_Numbe"],
                item => item["Customer_x0020_Street"],
                item => item["Customer_x0020_Suburb"],
                item => item["Customer_x0020_Postcode"],
                item => item["Organization"],
                item => item["Modified"],
                item => item["Created"]));

        ctx.ExecuteQuery();

        return collListItem;
    }
}

Also interested in whether there's a better way to tackle the problem than I have above.

2 Answers 2

6
private async Task<List<ListItem>> GetListItems(string filterField) {
    List<ListItem> items = new List<ListItem>();

    using (ClientContext context = SharePointContext.GetSharePointContext()) {
        List list = context.Web.Lists.GetByTitle("ListToRetrieveItems");
        int rowLimit = 100;
        ListItemCollectionPosition position = null;

        string viewXml = string.Format(@"
                <View>
                    <Query>
                        <Where>
                            <Eq>
                                <FieldRef Name='FilterField' />
                                <Value Type='Text'>{0}</Value>
                            </Eq>
                        </Where>
                    </Query>
                    <ViewFields>
                        <FieldRef Name='Title' />
                    </ViewFields>
                    <RowLimit>{1}</RowLimit>
                </View>", filterField, rowLimit);

        var camlQuery = new CamlQuery();
        camlQuery.ViewXml = viewXml;

        do {
            ListItemCollection listItems = null;
            if (position != null) {
                camlQuery.ListItemCollectionPosition = position;
            }

            listItems = list.GetItems(camlQuery);
            context.Load(listItems);
            Task contextTask = context.ExecuteQueryAsync();

            await Task.WhenAll(contextTask);

            position = listItems.ListItemCollectionPosition;

            items.AddRange(listItems.ToList());
        }
        while (position != null);
    }
    return items;
}
5
  • That would be the approach using rest, what about with CSOM (as shown in the question)?
    – Michael A
    Commented Aug 31, 2015 at 4:50
  • sorry about that, I edited my answer, please check it out Commented Aug 31, 2015 at 4:58
  • If you prefer, you can initialize the position variable like this: Commented Feb 28, 2018 at 16:16
  • var position = new ListItemCollectionPosition() // instead of null { PagingInfo = string.Empty }; Commented Feb 28, 2018 at 16:17
  • @AlexeyKrasheninnikov I don't think that's correct. I had exception "Unknown server" error thrown, when I initialize positions like you suggested. The var should be null initially (and finally).
    – Shihan
    Commented Mar 28, 2019 at 13:29
4

One can use the ListItemCollectionPosition class to implement paging list item retrieval according to the position of items relative to their collection. Use the RowLimit element to specify the number of items to return per page. The following example loops through all the items in a SharePoint list, using the ListItemCollectionPosition property of the CamlQuery class, and the ListItemCollectionPosition property of the ListItemCollection class.

ClientContext context = new ClientContext"Site URL");
 string username = @"username";
  string passw = @"password";
  SecureString passWord = new SecureString();
  foreach (char c in passw.ToCharArray()) passWord.AppendChar(c);
             {
     context.Credentials = new SharePointOnlineCredentials(username, passWord);

            }
  Web web = context.Web;
 try
         {
         int count = 0;
        List  Listname= context.Web.Lists.GetByTitle("name of the list");

         ListItemCollectionPosition itemPos = null;

          int intCount = 0;
          while (true)
               {
           CamlQuery cQuery = new CamlQuery();
             cQuery.ListItemCollectionPosition = itemPos;
             cQuery.ViewXml = "<View>"
               + " <RowLimit>1000</RowLimit>"
               + " </View>";

        Microsoft.SharePoint.Client.ListItemCollection items = Listname.GetItems(cQuery);
        context.Load(items);
        context.ExecuteQuery();
        itemPos = items.ListItemCollectionPosition;
        for (int iCntr = items.Count - 1; iCntr >= 0; iCntr--)

                    {

                      intCount++;
                      Microsoft.SharePoint.Client.ListItem listItem = items[iCntr];
                       listItem["Status"] = "Active";
             //Item is Retreivedinlistitem and now we are updating it to active
                      listItem.Update();
                     context.ExecuteQuery();

                    }

                    if (itemPos == null)

                    {

                        break;

                    }

                }

            }

            catch (Exception ex)

            {
               System.IO.StreamWriter file = new System.IO.StreamWriter("log Path", true);
                file.WriteLine(DateTime.Now + "    " + ex.Message);
                file.Close();



            }
0

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.