是否有一种“很好”的方式来创建一个类似于SharePoint的CAM的CAML查询?在CAML中相当于SQL IN
SELECT *
FROM table
WHERE Id IN (3, 12, ...)
还是我坚持嵌套<Or>
节点的梦魇?
编辑:这是我的解决方案,生成<Or>
节点。
/// Simulates a SQL 'Where In' clause in CAML
/// </summary>
/// <param name="columnType">Specifies the data type for the value contained by the field.</param>
/// <returns>Nested 'Or' elements portion of CAML query</returns>
public static string CamlIn<T>(string internalFieldName, string columnType, T[] values)
{
XDocument doc = new XDocument();
XElement prev = null;
int index = 0;
while (index < values.Length)
{
XElement element =
new XElement("Or",
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName)),
new XElement("Value",
new XAttribute("Type", columnType),
values[index++].ToString())));
if (index == values.Length - 1)
{
element.AddFirst(
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName)),
new XElement("Value",
new XAttribute("Type", columnType),
values[index++].ToString())));
}
if (prev != null)
prev.AddFirst(element);
else
doc.Add(element);
prev = element;
}
return doc.ToString(SaveOptions.DisableFormatting);
}
用法:
int[] ids = new int[] { 1, 2, 4, 5 };
string query = string.Format("<Where>{0}</Where>", CamlIn("SomeColumn", "Number", ids));
输出:
<Where>
<Or>
<Or>
<Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">5</Value>
</Eq>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">4</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">2</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name=\"SomeColumn\" />
<Value Type=\"Number\">1</Value>
</Eq>
</Or>
</Where>
也让这款超载与查找字段的工作更容易一点
/// <summary>
/// Simulates a SQL 'Where In' clause in CAML
/// </summary>
/// <param name="lookupId">Specify whether to use the Lookup column's Id or Value.</param>
/// <returns>Nested 'Or' elements portion of CAML query</returns>
public static string CamlIn<T>(string internalFieldName, bool lookupId, T[] values)
{
XDocument doc = new XDocument();
XElement prev = null;
int index = 0;
while (index < values.Length)
{
XElement element =
new XElement("Or",
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName),
lookupId ? new XAttribute("LookupId", "TRUE") : null),
new XElement("Value",
new XAttribute("Type", "Lookup"),
values[index++].ToString())));
if (index == values.Length - 1)
{
element.AddFirst(
new XElement("Eq",
new XElement("FieldRef",
new XAttribute("Name", internalFieldName),
lookupId ? new XAttribute("LookupId", "TRUE") : null),
new XElement("Value",
new XAttribute("Type", "Lookup"),
values[index++].ToString())));
}
if (prev != null)
prev.AddFirst(element);
else
doc.Add(element);
prev = element;
}
if (values.Length == 1)
{
XElement newRoot = doc.Descendants("Eq").Single();
doc.RemoveNodes();
doc.Add(newRoot);
}
return doc.ToString(SaveOptions.DisableFormatting);
}
不知道关于CAML.NET。将来可能需要使用它。我做了一些与XElements类似的事情来生成必要的''。 –
Chris
2009-12-12 22:37:45