Social Icons

miércoles, 11 de febrero de 2015

Se acabaron las funciones recursivas para definir CAML Queries gracias a Camlex

Algunas veces tienes un número aleatorio de condiciones para incluir en una CAML query y en esos casos yo solía definir las consultas usando una función recursiva que normalmente tenía que debugar unas cuantas veces me funciona siempre a la primera.

El código para este tipo de consultas sería algo así (y este es de los simples):

  1. public List<string> GetSomeInfo(string fieldsToSearch, string contentTypesToSearch)  
  2. {  
  3.     ...  
  4.   
  5.     var queryval = string.Empty;  
  6.     if (contentTypesToSearch.IsNullOrEmpty())  
  7.         queryval = string.Format("<Where>" + GenerateFieldsQuery(fieldsToSearch.Split(','), 0) + "</Where>", text);  
  8.     else  
  9.         queryval = string.Format("<Where><And>" + GenerateCTypesQuery(contentTypesToSearch.Split(','), 0) + GenerateFieldsQuery(fieldsToSearch.Split(','), 0) + "</And></Where>", text);  
  10.   
  11.     var scope = "Scope=\"RecursiveAll\"";  
  12.   
  13.     ...  
  14. }  
  15.   
  16. private static string GenerateFieldsQuery(string[] fields, int index)  
  17. {  
  18.     if (fields.Length == 0) return string.Empty;  
  19.   
  20.     if (fields.Length == index + 1)  
  21.         return "<Contains><FieldRef Name='" + fields[index] + "' /><Value Type='Text'>{0}</Value></Contains>";  
  22.   
  23.     return "<Or><Contains><FieldRef Name='" + fields[index] + "' /><Value Type='Text'>{0}</Value></Contains>" + GenerateFieldsQuery(fields, ++index) + "</Or>";  
  24. }  
  25.   
  26. private static string GenerateCTypesQuery(string[] cTypes, int index)  
  27. {  
  28.     if (cTypes.Length == 0) return string.Empty;  
  29.   
  30.     if (cTypes.Length == index + 1)  
  31.         return "<Eq><FieldRef Name='ContentType' /><Value Type='Choice'>" + cTypes[index] + "</Value></Eq>";  
  32.   
  33.     return "<Or><Eq><FieldRef Name='ContentType' /><Value Type='Choice'>" + cTypes[index] + "</Value></Eq>" + GenerateCTypesQuery(cTypes, ++index) + "</Or>";  
  34. }  

Eso era hasta ahora... gracias a Camlex (y gracias a Luis por decírmelo), este código se puede escribir así:

  1. public List<string> GetSomeInfo(string fieldsToSearch, string contentTypesToSearch)  
  2. {  
  3.     ...  
  4.   
  5.     var queryVal = string.Empty;  
  6.     var fieldExtensions = new List<Expression<Func<SPListItem, bool>>>();  
  7.     var cTypeExtensions = new List<Expression<Func<SPListItem, bool>>>();  
  8.   
  9.     if (!contentTypesToSearch.IsNullOrEmpty())  
  10.     {  
  11.         foreach (var cType in contentTypesToSearch.Split(','))  
  12.             cTypeExtensions.Add(x => (string)x["ContentType"] == cType);  
  13.     }  
  14.   
  15.     foreach (var field in fieldsToSearch.Split(','))  
  16.         fieldExtensions.Add(x => ((string)x[field]).Contains(text));  
  17.   
  18.     var expressions = new List<Expression<Func<SPListItem, bool>>>();  
  19.     expressions.Add(ExpressionsHelper.CombineOr(cTypeExtensions));  
  20.     expressions.Add(ExpressionsHelper.CombineOr(fieldExtensions));  
  21.   
  22.     queryVal = Camlex.Query().WhereAll(expressions).ToString();  
  23.   
  24.     ...  
  25. }  

Echaré de menos los métodos recursivos... me hacían sentir especial...

No hay comentarios: