3

I'm having trouble querying SharePoint in such a way, as to combine a view results with my own CAML query inside a WCF service. It seems GetItems ignores my query, and just returns all the items in the view regardless.

Here's the sample code I'm trying out right now:

    public bool Test()
    {
        using (SPSite site = SPContext.Current.Site)
        {
            using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
            {
                var list = web.Lists["Test"];
                var caml = "<Where><Eq><FieldRef Name=\"Field2\" /><Value Type=\"Boolean\">1</Value></Eq></Where>";
                var view = list.Views["TestView"];
                var query = new SPQuery();
                query.Query = caml;
                List<SPListItem> viewWithCamlItems = new List<SPListItem>();
                SPListItemCollection results;
                do
                {
                    results = list.GetItems(query, view.ID.ToString("B").ToUpper());
                    results.Cast<SPListItem>().ToList().ForEach(i => viewWithCamlItems.Add(i));
                    query.ListItemCollectionPosition = results.ListItemCollectionPosition;
                } while (results.ListItemCollectionPosition != null);
                var camlOnlyResults = list.GetItems(new SPQuery() { Query = caml }).Cast<SPListItem>().ToList();
                var x = viewWithCamlItems.Count;
                var y = camlOnlyResults.Count;
                return x == y;
            }
        }
    }

The list in question has only 2 columns: Field1 and Field2, and both of these are Yes/No columns. The view displays only those rows where Field1 is True. At the moment of writing this question, I've only got 1 row in the list where Field2 is True; considering the camlOnlyResults contains just that one row I think the CAML is correct, and I'd expect x and y to be equal...

However, I get all rows in viewWithCamlItems inside the view...

What am I doing wrong?

EDIT: The reason I'm using paging in one case and not the other, is because the view might have a small row limit, while the default SPQuery has a row limit of uint.MaxValue, which is plenty.

2 Answers 2

1

Instead of

results = list.GetItems(query, view.ID.ToString("B").ToUpper()); 

You should just use

results = list.GetItems(query); 

Otherwise you get the where clause from the view as stated in the Remarks to public SPListItemCollection GetItems( SPQuery query, string viewName )

The properties of the view that is specified by the viewName parameter override the properties that are specified in the query object that is passed through the query parameter. For example, if the query object includes a tag that specifies only items containing a particular column value, while the view specifies to return all items, this method retrieves all of the items

2
  • Aye, I missed that part initially. Is there any way to combine CAML filtering with that provided by a view?
    – MBender
    Commented Jun 26, 2012 at 13:21
  • You can pass the view to the constructor SPQuery(SPView view) which will initialize several of the properties in the SPQuery with the corresponding fields from the view, but in most cases this isn't what you want as the enduser may change the query in ways which may cause problems for your code. So usually it's best to build the entire query in code, but as always it depends on what you need. Commented Jun 26, 2012 at 15:13
1

You need to use <Value Type=\"Bool\">1</Value>, rather than Boolean when querying on boolean fields.

For camlOnlyResults it looks like you're casting the list to a single element, which is why the result of ToList contains only a single element.

1
  • Since var camlOnlyResults = list.GetItems(new SPQuery() { Query = caml }).Cast<SPListItem>().ToList(); returns the correct results I think the CAML is OK.
    – MBender
    Commented Jun 26, 2012 at 13:20

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.