Better logic to create CAML queries
-
07-10-2020 - |
Pergunta
Assume i have 3 checkboxes in my webpart Properties. Checkboxes are for selecting categories.
In my SharePoint list i have multichoice column called category and values in it are CAT1,CAT2 and CAT3
If user Selects any of those checkbox or combination of those checkboxes then how can i build dynamice CAML Query. Write now i am writing School boyish stuff like below
var IsCAT1Selected = false;
var IsCAT2Selected = false;
var IsCAT3Selected = false;
// retrieve Properties selected
IsCAT1Selected = ParentWebPart._CAT1property;
IsCAT2Selected = ParentWebPart._CAT2property;
IsCAT3Selected = ParentWebPart._CAT3property;
SPQuery query = new SPQuery();
if (IsCAT1Selected){
query.Query = "<Where><Eq><FieldRef Name ='Category'/><Value Type ='MultiChoice'>CAT1</Value></Eq></Where> ";
}
if (IsCAT2Selected){
query.Query = "<Where><Eq><FieldRef Name ='Category'/><Value Type ='MultiChoice'>CAT2</Value></Eq></Where> ";
}
if (IsCAT3Selected){
// same Query as above except pass value as "CAT3"
}
If (IsCAT1Selected && IsCAT2Selected){
query.Query = "<Where><Or><Contains><FieldRef Name ='Category'/><Value Type ='MultiChoice'>CAT1</Value></Contains><Contains><FieldRef Name ='Category'/><Value Type ='MultiChoice'>CAT2</Value></Contains></Or></Where> ";
}
if (IsCAT1Selected && IsCAT3Selected){
//same Query as above except changing values to CAT1 and CAT3
}
If checkboxes increases then Logic will become even more complicated. I have Write several combinations.
How can i Write simple Logic for this?
Solução
By using code from How to build a CAML query with several nested OR's using a loop and its answser https://sharepoint.stackexchange.com/a/167266/35604, you can easily simplify your code.
Now you have all these methods that help you building nested Or
and And
queries, simply do this:
List<string> queries = new List<string>();
if (IsCAT1Selected)
queries.Add(QueryEq("Category", "MultiChoice", "CAT1"));
if (IsCAT2Selected)
queries.Add(QueryEq("Category", "MultiChoice", "CAT2"));
if (IsCAT3Selected)
queries.Add(QueryEq("Category", "MultiChoice", "CAT3"));
query.Query = QueryBody(RecursiveNestedOr(queries));
Outras dicas
There is no good solutions to this, other than creating a string and appending subqueries underneath. I faced this a few years back, and ended up with appending subqueries to a big query.
Though, you should go away with all the combinations. Instead having something like this :
List<string>partCollection = new List<string>();
if (IsCAT1Selected){
partCollection.Add("<Eq><FieldRef Name ='Category'/><Value Type='MultiChoice'>CAT1</Value></Eq>");
}
and then combine with
string fullQuery ="<Where>";
foreach (var part in partCollection)
{
fullQuery += "<Or>" +part +"</Or>"
}
fullQuery +="</Where>";
Its a bit more complex to it, since you need to pair the part queries so the 'OR' works.