3

I'm running a number of CAML queries against a large list in SharePoint 2010, and displaying the results in a gridview to the end user. I wish to page through the results returned by the query to improve performance. However, I am required to display a total count of the items returned by the query on the paging control. My question is, how can I determine the total number of items that will be returned by each query without actually returning them all in a single SPListItemCollection? To be precise, I wish to page through the results 10 items at a time; how can I do this and still have a total count of all items returned by the query?

Update

So far, none of the answers given have addressed my question - as such, I'm offering a bounty. I need to be able to get a total count of the number of items that a CAML query will return without having to run the query and return all of the items. This will enable me to display this total count value to the end user (a set requirement), while paging through the items collection to display a specific page of results in a gridview. This would avoid a massive performance hit for large lists on the page containing the gridview first loading.

If no one offers a valid answer to the above, I will accept an answer that gives a link to an MSDN article that explicitly says that the above functionality cannot be implemented.

Thanks, MagicAndi.

Tangiest
  • 43,737
  • 24
  • 82
  • 113
  • 1
    Have you tried using the search API? For large lists, going to the index will give you the count quickly. If you run incremental crawls often it will be exactly right after each crawl before adds or deletes. – Tom Resing Nov 02 '10 at 15:35
  • Tom, interesting idea. But in some cases, I require the total count of items after a filter has been applied - hence the requirement to determine the number of items in a view/CAML query as opposed to just the number of items in a list. – Tangiest Nov 02 '10 at 15:45
  • Tom, also, this is the best answer I've received so far - add it as an answer, and if no better answer comes in the next few 6 days, you'll get the 50 reps. Thanks. – Tangiest Nov 02 '10 at 15:46
  • Use SVC to get count `https://.com//_vti_bin/ListData.svc//$count` – Display_Here Jun 29 '16 at 16:49

8 Answers8

8

Unfortunately, I don't think you're going to get a definitive answer from MSDN saying what isn't possible... only what is. Here is the entire CAML Query Schema page on msdn. There is no mention of any type of "count" function there.

As for solving your problem, first you need to choose the correct method for finding items. For example, here are a couple cases:

  1. Items from one list? CAML
  2. Items from a couple lists in the same site? SPSiteDataQuery
  3. Items from many lists in many sites? Search API

Second, you can implement some sort of caching in your web part to reduce the time it takes to sort/page/filter. I like using the System.Web.HttpRuntime.Cache to store a DataTable (makes it easy to change the method for retrieving items while your grid can keep using the datatable). You could also use Page.Session instead of caching.

Kit Menke
  • 7,046
  • 1
  • 32
  • 54
2

It is a SharePoint limitation. This is why SharePoint doesn't show how many pages you have in view.

cement
  • 2,905
  • 1
  • 23
  • 20
  • Cement, thanks, this is what I thought. Can you point me towards a MSDN reference for this? – Tangiest Oct 27 '10 at 15:37
  • No feature - no MSDN reference :) Only forums http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/1ac0cd45-8ba2-439f-b534-bc05573ae33e – cement Oct 27 '10 at 16:00
2

You can create a view for that list with items per page limited to say 10. Then use a listview control (instead of gridview) and bind the view.

sssreddy
  • 282
  • 1
  • 3
  • 15
  • sssreddy, thanks for your reply. Unfortunately, I have already looked at using the XSLTListViewWebPart to display the list, but I wasn't able to customize the control to display a total count. This is a set customer requirement. – Tangiest Oct 29 '10 at 09:23
  • sssreddy, no, unfortunately not. In addition to displaying a set number of items per page, the customer requires that the total number of items in the current view of the list (including any filtering criteria being applied) is displayed in the pager control. It is not possible to update the list view control to include this total count of items in the view. – Tangiest Oct 29 '10 at 14:56
  • If I understand right, you want a count of the number of items displayed per page. {SPList list = web.lists["TestList"]; SPViewCollection viewCollection = list.Views; stringCollection listofFieldstodisplay = new stringCollection; listofFieldtodisplay.Add("Field1"); viewCollection.Add("NamoftheNewView",listofFieldtodisplay,CAMLQUERY, 10,true,false;} .. Now on UI... { Microsoft.SharePoint.ListView myListView = null; myListView.ID = list.ID; myListView.view = list.views["nameofthenewview"]; mylistview.Databind(); } .. – sssreddy Oct 29 '10 at 15:08
  • As we mentioned 10 items and set pagination as true, it will always display only 10 items per page. Litview will automatically display the which set of 10 items it is displaying. Hope this solves your problem. – sssreddy Oct 29 '10 at 15:09
  • Also filtering, sorting are automaticallly handled – sssreddy Oct 29 '10 at 15:45
2

Sorry it seams the CAML query didn't go through... so once again

    <Aggregations Value="On">
        <FieldRef Name="LinkTitle" Type="COUNT"/>
    </Aggregations>
1

Just spent couple of hours trying to figure out how to do that.... Below is a list of things that you need to do to get the full list count.

1) Modify the list view that you are accessing and within the totals add COUNT to one of the Columns

2) Add the following code to the CAML query within your webpart

3) Add the following code for displaying the count

            <xsl:value-of select="/dsQueryResponse/Rows/Row/@*[name()='YOUR_COLUMN_NAME_FROM_FIRST_STEP.COUNT']"/>

And enjoy... I have checked it with and without Filter.

Art

0

Is possible two solutions, both with limitations:

  • perform lightweight query with no defined viewfields
  • use 'unlimited pager'(ex. if you use DataGrid, set VirtualItemCount to 10K or above)
gdbdable
  • 4,445
  • 3
  • 30
  • 46
0

I have only found a "dirty" way that's totally outside anything supported :) I've created a view on the database and abused SQL server to count for me. Totally broken and totally non supported and absolutely going to bite myself but the only way I've found to get a count on a large set of records. Did not use it as it's not safe for production.

Edit: all list data is dumped into one huge table AllUserData and if you have the tp_listid you can create a count

SELECT        COUNT(nvarchar7) AS Expr1
FROM          dbo.AllUserData
WHERE        (tp_ListId = 'xxxxxxxx-9999-3333-7777-yyyyyyyyyyyy')

But then you have to start filtering for versions if you use them

WHERE        (tp_Version =
             (SELECT        MAX(tp_Version) AS ex1
             FROM            {{view above}} AS V1
             WHERE        (key = M.key)))

etc etc. You can get the count and you can get it very fast but foot meet gun.....

0

Don't know if we are on the same page... but you can count items received by SPQuery quite simple:

   SPQuery query = new SPQuery();
   query.Query = string.Concat(
                  "<Where><Eq>",
                     "<FieldRef Name='Status'/>",
                     "<Value Type='CHOICE'>Not Started</Value>",
                  "</Eq></Where>",
                  "<OrderBy>",
                     "<FieldRef Name='DueDate' Ascending='TRUE' />",
                     "<FieldRef Name=’Priority’ Ascending='TRUE' />", 
                  "</OrderBy>");                    


   SPListItemCollection items = list.GetItems(query);
   double totalCount = items.Count;

Maybe this is your solution.

HelpNeeder
  • 6,383
  • 24
  • 91
  • 155
Robert Kuzma
  • 143
  • 1
  • 4
  • 9
  • 1
    Robert, thanks for your answer. The problem is, this solution retrieves **ALL** the items in the list that match the criteria. In the case I discussed above, this was approx. 80,000 items, which obviously had a significant performance impact. My question was asking how to determine the total count of items returned by a specific query without actually running it. – Tangiest Dec 06 '11 at 10:44