1

I'm new to SharePoint development and I need your help to solve this issue.I've created a CAMLQuery builder class.

public class CAMLQueryBuilder
{
    #region Builder part

public static string QueryBody(string clause1)
{
    return "<Where>" + clause1 + "</Where>";
}

public static string QueryAnd(string clause1, string clause2)
{
    return "<And>" + clause1 + clause2 + "</And>";
}
public static string QueryOr(string clause1, string clause2)
{
    return "<Or>" + clause1 + clause2 + "</Or>";
}

public static string QueryEq(string fieldName, string fieldType, string fieldValue)
{
    return string.Format("<Eq><FieldRef Name='{0}'/><Value Type='{1}'>{2}</Value></Eq>", fieldName, fieldType, fieldValue);
}
#endregion
}

Now I have List<string>positions which may contain more than one string, and for each position Employee can see some info regarding some rules(if he is office director , he can see everything from his office, if he is delivery manager everything from his department).Now I need idea how can I build multiple OR query after going through the for loop. I want a query that will have as many nested OR's as there are positions at the and of for loop.

This is the basic structure of the code, I need your help to make it work. I've created generic recursive method in case there will be more than one positions to generate nested OR's.

public static string RecursiveNestedOr(int count, List<string> query) 
{
//please if you have another idea for naming this method
   if (count == 1)
   {
       return query[0];
   }
    else
    {
      return CAMLQueryBuilder.QueryOr(query[count-1], RecursiveNestedOr(--count, query));
    }
  }

Then I make a query string for each of the position and add it to Listqueries.After that I use recursive method and send list of queries as a parameter to it.

for (int i = 0; i < positions.Count - 1; i++)
{
  switch (positions[i])
  {
    case ("OfficeDirector"): query = CAMLQueryBuilder.QueryEq("Office", "Choice", emp.Offices[i]);
       break;
    case ("DeliveryManager"): query = CAMLQueryBuilder.QueryEq("Department", "Choice", emp.Departments[i]);
       break;
    default:query = "";
       break;
  }
   queries.Add(query);

}
   query = CAMLQueryBuilder.QueryBody(CAMLQueryBuilder.RecursiveCAMLOr(queries.Count, queries));
//this is only basic idea 

Is there any other solution ? More elegant ? Thank you!

1 Answer 1

1

You don't need to pass count as a parameter as you can get it from queries Inside the method RecursiveNestedOr itself (also, rename parameter query as queries).

Otherwise, your recursion looks fine to me. Here's how I'd "simplified" it, using LINQ (add using System.Linq):

public static string RecursiveNestedOr(IEnumerable<string> queries)
{
    if (queries == null || queries.Count() == 0)
        return "";

   if (queries.Count() == 1)
       return queries.First();

    // Now queries.Count is at least 2
    return CAMLQueryBuilder.QueryOr(queries.Last(), RecursiveNestedOr(queries.Take(queries.Count() - 1)));
}

EDIT:
Here's how to do it without recursion (code not tested):

public static string NestedOr(IEnumerable<string> queries)
{
    if (queries == null || queries.Count() == 0)
        return "";

   if (queries.Count() == 1)
       return queries.First();

   string result = queries.First();

   // Now queries.Count is at least 2

   foreach(string query in queries.Skip(1))
   {
      result = QueryOr(result, query);
   }

    return result;
}
5
  • Thank you Evariste great idea.However , this code has some errors, VS is showing Operator '==' cannot be applied to operands of type 'method group' and 'int' , because Enumerable.Count is an extension method.So correct answer will be queries.Count(), Commented Jan 15, 2016 at 13:22
  • Yup, you're correct; or .Length probably. I edited my answer.
    – Evariste
    Commented Jan 15, 2016 at 13:25
  • Do you know any other way for creating a nested OR query like this which is not a recursion ? Commented Jan 15, 2016 at 13:34
  • You could probably do it with a simple for loop, but that would be less elegant IMO. I code it as you do.
    – Evariste
    Commented Jan 15, 2016 at 13:35
  • Updated my answer to provide a sample without recursion.
    – Evariste
    Commented Jan 15, 2016 at 13:39

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.