usar una tipos subconsultas resultado poner otro otra nombre dentro datos consulta sharepoint caml nested-query

sharepoint - una - Consulta CAML con AND anidados y OR para mĂșltiples campos



tipos de subconsultas sql (3)

Estoy trabajando en el código de prueba de concepto para generar CAML dinámicamente en base a las palabras clave proporcionadas a un servicio web de búsqueda altamente específico que estoy escribiendo. No estoy utilizando el servicio web de búsqueda proporcionado por SharePoint para esta prueba. Ya lo hice por lo que estoy tratando de lograr. De toda mi investigación, no puedo encontrar un ejemplo cercano de lo que estoy tratando de lograr, que es verificar múltiples campos para valores múltiples. Sí, ya he consultado SO por mi respuesta, incluida esta: necesito ayuda para construir CAML Query .

Dicho esto, si es posible, ¿cómo se puede escribir la siguiente consulta tipo SQL en CAML?

SELECT FirstName, LastName, Description, Profile FROM SomeFakeTable WHERE (FirstName = ''John'' OR LastName = ''John'' OR Description = ''John'' OR Profile=''John'') AND (FirstName = ''Doe'' OR LastName = ''Doe'' OR Description = ''Doe'' OR Profile=''Doe'') AND (FirstName = ''123'' OR LastName = ''123'' OR Description = ''123'' OR Profile=''123'')


Como no puede poner más de dos condiciones en un grupo de condiciones (Y | O), debe crear un grupo anidado adicional ( MSDN ). La expresión A AND B AND C ve así:

<And> A <And> B C </And> </And>

Su SQL como muestra traducida a CAML (con suerte con etiquetas XML que coincidan;)):

<Where> <And> <Or> <Eq> <FieldRef Name=''FirstName'' /> <Value Type=''Text''>John</Value> </Eq> <Or> <Eq> <FieldRef Name=''LastName'' /> <Value Type=''Text''>John</Value> </Eq> <Eq> <FieldRef Name=''Profile'' /> <Value Type=''Text''>John</Value> </Eq> </Or> </Or> <And> <Or> <Eq> <FieldRef Name=''FirstName'' /> <Value Type=''Text''>Doe</Value> </Eq> <Or> <Eq> <FieldRef Name=''LastName'' /> <Value Type=''Text''>Doe</Value> </Eq> <Eq> <FieldRef Name=''Profile'' /> <Value Type=''Text''>Doe</Value> </Eq> </Or> </Or> <Or> <Eq> <FieldRef Name=''FirstName'' /> <Value Type=''Text''>123</Value> </Eq> <Or> <Eq> <FieldRef Name=''LastName'' /> <Value Type=''Text''>123</Value> </Eq> <Eq> <FieldRef Name=''Profile'' /> <Value Type=''Text''>123</Value> </Eq> </Or> </Or> </And> </And> </Where>


Este código generará dinámicamente la expresión para usted con las cláusulas anidadas. Tengo un escenario donde el número de "O" era desconocido, entonces estoy usando el siguiente. Uso:

private static void Main(string[] args) { var query = new PropertyString(@"<Query><Where>{{WhereClauses}}</Where></Query>"); var whereClause = new PropertyString(@"<Eq><FieldRef Name=''ID''/><Value Type=''Counter''>{{NestClauseValue}}</Value></Eq>"); var andClause = new PropertyString("<Or>{{FirstExpression}}{{SecondExpression}}</Or>"); string[] values = {"1", "2", "3", "4", "5", "6"}; query["WhereClauses"] = NestEq(whereClause, andClause, values); Console.WriteLine(query); }

Y aquí está el código:

private static string MakeExpression(PropertyString nestClause, string value) { var expr = nestClause.New(); expr["NestClauseValue"] = value; return expr.ToString(); } /// <summary> /// Recursively nests the clause with the nesting expression, until nestClauseValue is empty. /// </summary> /// <param name="whereClause"> A property string in the following format: <Eq><FieldRef Name=''Title''/><Value Type=''Text''>{{NestClauseValue}}</Value></Eq>"; </param> /// <param name="nestingExpression"> A property string in the following format: <And>{{FirstExpression}}{{SecondExpression}}</And> </param> /// <param name="nestClauseValues">A string value which NestClauseValue will be filled in with.</param> public static string NestEq(PropertyString whereClause, PropertyString nestingExpression, string[] nestClauseValues, int pos=0) { if (pos > nestClauseValues.Length) { return ""; } if (nestClauseValues.Length == 1) { return MakeExpression(whereClause, nestClauseValues[0]); } var expr = nestingExpression.New(); if (pos == nestClauseValues.Length - 2) { expr["FirstExpression"] = MakeExpression(whereClause, nestClauseValues[pos]); expr["SecondExpression"] = MakeExpression(whereClause, nestClauseValues[pos + 1]); return expr.ToString(); } else { expr["FirstExpression"] = MakeExpression(whereClause, nestClauseValues[pos]); expr["SecondExpression"] = NestEq(whereClause, nestingExpression, nestClauseValues, pos + 1); return expr.ToString(); } } public class PropertyString { private string _propStr; public PropertyString New() { return new PropertyString(_propStr ); } public PropertyString(string propStr) { _propStr = propStr; _properties = new Dictionary<string, string>(); } private Dictionary<string, string> _properties; public string this[string key] { get { return _properties.ContainsKey(key) ? _properties[key] : string.Empty; } set { if (_properties.ContainsKey(key)) { _properties[key] = value; } else { _properties.Add(key, value); } } } /// <summary> /// Replaces properties in the format {{propertyName}} in the source string with values from KeyValuePairPropertiesDictionarysupplied dictionary.nce you''ve set a property it''s replaced in the string and you /// </summary> /// <param name="originalStr"></param> /// <param name="keyValuePairPropertiesDictionary"></param> /// <returns></returns> public override string ToString() { string modifiedStr = _propStr; foreach (var keyvaluePair in _properties) { modifiedStr = modifiedStr.Replace("{{" + keyvaluePair.Key + "}}", keyvaluePair.Value); } return modifiedStr; } }