CAML Query with NotIncludes Fails when using Contains - sharepoint

I have the following CAML query which works perfectly:
var emergencyCAML = "<View><Query><Where><And><Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[0] + "</Value></Contains><Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[1] + "</Value></Contains></And></Where><OrderBy><FieldRef Name='Title' Ascending='TRUE' /></OrderBy></Query></View>";
However,
When I add the notIncludes it doesn't bring any results.
var emergencyCAML = "<View><Query><Where><And><Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[0] + "</Value></Contains><Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[1] + "</Value></Contains><NotIncludes><FieldRef Name = 'Hidden' LookupId='True'/><Value Type = 'Lookup'>" + _spPageContextInfo.userId + "</Value><XML /></NotIncludes></And></Where><OrderBy><FieldRef Name='Title' Ascending='TRUE' /></OrderBy></Query></View>";

Each element can only contain two child elements. Your version with the not includes violates that. Try fixing it by wrapping the in another tag to ensure the first And only has two direct child elements. Like this:
<View>
<Query>
<Where>
<And>
<And>
<Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[0] + "</Value></Contains>
<Contains><FieldRef Name='Project_x0020_Members'/><Value Type='Note'>" + searchTerms[1] + "</Value></Contains>
</And>
<NotIncludes><FieldRef Name = 'Hidden' LookupId='True'/><Value Type = 'Lookup'>" + _spPageContextInfo.userId + "</Value><XML /></NotIncludes>
</And>
</Where>
<OrderBy><FieldRef Name='Title' Ascending='TRUE' /></OrderBy>
</Query>
</View>
More info: https://msdn.microsoft.com/en-us/library/office/ms196939.aspx
Remarks
This element can be nested inside other And and Or elements. The server supports unlimited complicated queries. However, any given And element can have only two conjuncts; that is, only two child elements. If you need to conjoin three or more conditions, you must nest the And elements, as demonstrated by the third example in the following section.

Related

SharePoint Online: Get Document Library Children Count Using CSOM

My requirement is to get the children item count of Document Library using CSOM. The count should only be the immediate children count, and should not include the sub-children count. I am trying to use below code to achieve this:
var newObjClientContext = this.GetSharePointClientContext(accessToken, fullUri);
WebCollection collWeb = newObjClientContext.Web.GetSubwebsForCurrentUser(new SubwebQuery());
var documentLibrary = newObjClientContext.Web.Lists.GetById(docID);
ListItemCollection ltitems = null;
string vquery = #"<View >
<Query>
<Where>
<Or>
<Eq>
<FieldRef Name='FSObjType' />
<Value Type='Lookup'>1</Value>
</Eq>
<Eq>
<FieldRef Name='FSObjType' />
<Value Type='Lookup'>0</Value>
</Eq>
</Or>
</Where>
<OrderBy><FieldRef Name='FileLeafRef' Ascending='TRUE'></FieldRef></OrderBy>
</Query>
<RowLimit>" + recCount + #"</RowLimit>
</View>";
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = vquery;
ltitems = documentLibrary.GetItems(camlQuery);
newObjClientContext.Load(documentLibrary);
newObjClientContext.Load(ltitems, lists => lists.IncludeWithDefaultProperties(l => l.ParentList));
newObjClientContext.ExecuteQuery();
int totalcount = documentLibrary.ItemCount; //It includes count of all the items present at all levels.
Can anyone suggest how can I get children count in above step?
If I have interpreted your requirement correctly you want the root level child item count of the document library? This is easily achieved using the ItemCount property of document libraries RootFolder.
var list = web.Lists.GetByTitle("Documents");
cc.Load(list.RootFolder, l => l.ItemCount);
cc.ExecuteQuery();
var rootChildItemCount = list.RootFolder.ItemCount;
Or do you require the child item count of every folder in your document library? This can be achieved with a CamlQuery. Let me know if your require a solution for this.

CAML person or Group field with Multiple values

I have a Field with Name TargetedPeople in a Sharepoint list. This is a Person or User group which can have multiple values.
The CAML I used for Querying is
siteDataQuery.Query = #"<Where><Includes><FieldRef Name='TargetedPeople' LookupId='TRUE'/><Value Type='Integer'>" + webInContext.CurrentUser.ID + "</Value></Includes></Where>";
This works fine if we have set the Allow Multiple Selections for "No" in the field. But this seems like not working for if it set to "Yes".
Please share me how to query a multiple field.
After some changes I was able to figure out this. If the field has multiple values we should define the value Type as LookupMulti. Following is the working code sample
siteDataQuery.Query = #"<Where><Contains><FieldRef Name='TargetedPeople' LookupId='TRUE'/><Value Type='LookupMulti'>" + webInContext.CurrentUser.ID + "</Value></Contains></Where>";
Also works and looks like simpler (tested on SP Online):
<Contains>
<FieldRef Name='TargetedPeople' />
<Value Type="Integer">
<UserID Type="Integer" />
</Value>
</Contains>

Query on Date Fields using CAML

I am trying to run a query against a sharepoint list (using the client object model), finding an item that matches on a date field.
My query is:
2012-07-24T02:50:28
1
I know that there is an item in the list where the EmDateSent field has the value 2012-07-24T02:50:28 and yet when I run this I get 0 rows back.
Having spent hours researching and experimenting I found that the date formatting I have used works - or so I thought. It seems that now it doesn't.
My code is below.
Can anybody suggest something else I can try?
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = String.Format(
#"<View>
<Query>
<Where>
<Eq>
<FieldRef Name='{0}'/>
<Value Type='DateTime' IncludeTimeValue='True'>{1}</Value>
</Eq>
</Where>
</Query>
</View>", EMAIL_FIELD_DATE_SENT, details.DateSent.HasValue ? details.DateSent.Value.ToString("yyyy-MM-ddTHH:mm:ss") : "");
ListItemCollection listItems = upLoadList.GetItems(camlQuery);
_context.Load(listItems);
_context.ExecuteQuery();
if (listItems.Count > 0) // At this point I expect listItems.Count to be 1, but it is 0
{
....
Your example looks correct, and there is not an issue with using the "T" in the time stamp. However, from what I can find, most of the examples like yours use the SPQuery class instead of the CamlQuery class. I believe this is causing your issue.

Logical AND ,OR CAML Query not working in External List

I am using ClientContext Class and CAML query to retrieve items from External List in sharepoint 2010.I have built the query with Logical AND Condition in CAML Query like this
string sDataFilter =<Query><Where><And><Eq><FieldRef Name="Year" /><Value Type="Text">1960</Value></Eq><Contains><FieldRef Name="ChartName" /><Value Type="Text">Chart1</Value></Contains></And></Where></Query>
When I exceute the following code
List oList = clientContext.Web.Lists.GetById(new Guid(list));
CamlQuery camlQuery = new CamlQuery();
string queryContext = "<View><Query>" + sDataFilter + "</Query>" + viewFieldsContext + "</View>";
camlQuery.ViewXml = queryContext;
ListItemCollection collListItem = oList.GetItems(camlQuery);
clientContext.Load(collListItem);
clientContext.ExecuteQuery();
I am getting the empty ListItemCollection.I have cross verified with the U2U CAML Query Builder the data is empty only. So in External List the caml query is working fine for sorting and simple filter query like Where,EqualTo condition I can't use Logical conditions in the query ? If yes how could I achieve this using caml query
Could anyone help me to resolve this issue ?
The problem is below line of code
string queryContext = "<View><Query>" + sDataFilter + "</Query>" + viewFieldsContext + "</View>";
change this line with follwing code
string queryContext = "<View>" + sDataFilter + viewFieldsContext + "</View>";
the problem is in Query tag. It's two time repeat in query.
late me know when it's working
Thax

Using CAML to compare SharePoint "Person or Group" fields

I have a SharePoint 2007 (MOSS) list with 2 "Person or Group" columns which I would like to compare, essentially:
SELECT * FROM List WHERE (Analyst = Developer)
In my code (C#) I've built this as:
SPQuery itemQuery = new SPQuery();
itemQuery.Query = "<Where><Eq><FieldRef Name='Analyst' /><FieldRef Name='Developer' /></Eq></Where>";
SPListItemCollection queryResults = list.GetItems(itemQuery);
But this is throwing an exception ("Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION)").
I've seen some information regarding the Type attribute of a Value element when comparing against a "Person or Group" column, but nothing about comparing two of these columns against each other.
I've also tried adding "LookupId='TRUE'" to each FieldRef, with no change.
It is not possible to compare two fields like that using CAML. You have to use a literal value. This means, that you'll likely have two queries:
Retrieve the Analyst/Developer's user ID
Retrieve items where Analyst and Developer are the same
Example of #2:
<Where>
<And>
<Eq><FieldRef Name="Analyst" LookupId="TRUE"/><Value Type="Integer">42</Value></Eq>
<Eq><FieldRef Name="Developer" LookupId="TRUE"/><Value Type="Integer">42</Value></Eq>
</And>
</Where>
FYI, you can also use <UserID/> for the "Current User" instead of user ID (in this example, 42).
The logic you are looking for, I believe, is this:
<Where>
<Eq>
<FieldRef Name='Analyst'/>
<Value Type="Text"><FieldRef Name='Developer'/></Value>
</Eq>
</Where>
I tested and this is not possible so the two options, as I see it, are:
Get all list items , then iterate through with JQuery with a find and compare for the two fields being equal.
Create a calculated column that sets a true or false value if the two columns are equal in the list and then do your select based on that column. This is probably the most expedient and also most effective from a performance perspective.
Try this:
<Where>
<Eq>
<FieldRef Name="Analyst" />
<Value Type="Text">Developer</Value>
</Eq>
</Where>
I have found a list that has two matching values to compare and I got a CAML query to work with the comparison; however, it is a boolean value so I am not sure if this is what you are looking for. It does compare two fields but I think the literal is still getting in the way. This list has about 25 entries in it and this is the only one that matched so I thought this would be a good test.
Here is the code:
private DataTable ExecuteQuery(SPList list)
{
SPQuery qry = new SPQuery();
qry.Query = "<Where><And><Contains><FieldRef Name='Show' /><Value Type='Boolean'>1</Value></Contains><Contains><FieldRef Name='Highlight' /><Value Type='Boolean'>1</Value></Contains></And></Where>";
qry.ViewFields = "<FieldRef Name='Show' /><FieldRef Name='Highlight' />";
qry.IncludeMandatoryColumns = true;
return list.GetItems(qry).GetDataTable();
Sorry if this is not what you are looking for. Good Luck!!

Resources