我正在研究概念验证代码,以根据提供给我正在编写的高度特定的搜索Web服务的关键字动态生成CAML。我没有使用SharePoint提供的搜索Web服务来进行此证明。我已经为我想要实现的目标做了这样的事情。从我的所有研究中,我找不到我想要实现的一个接近的例子,即检查多个值的多个字段。是的,我已经看过SO了我的回答,包括这个:Need help on building CAML Query。
话虽如此,如果有可能,如何在CAML中编写以下类似SQL的查询?
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')
答案 0 :(得分:53)
由于不允许在一个条件组(And | Or)中放置两个以上的条件,因此必须创建一个额外的嵌套组(MSDN)。表达式A AND B AND C
如下所示:
<And>
A
<And>
B
C
</And>
</And>
您的SQL样本示例已转换为CAML(希望使用匹配的XML标记;)):
<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>
答案 1 :(得分:0)
您可以尝试U2U查询构建器http://www.u2u.net/res/Tools/CamlQueryBuilder.aspx,您可以使用他们的API U2U.SharePoint.CAML.Server.dll和U2U.SharePoint.CAML.Client.dll
我没有使用它们,但我相信它会帮助你完成任务。
答案 2 :(得分:0)
此代码将使用嵌套子句为您动态生成表达式。我有一个场景,其中“OR”的数量是未知的,所以我使用下面的。用法:
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);
}
这是代码:
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;
}
}