Camlex.NET for Windows SharePoint Services






4.25/5 (3投票s)
Camlex.NET 通过使用表达式树简化了 Windows SharePoint Services 的 CAML 查询创建过程
引言
Camlex.NET ( http://camlex.codeplex.com ) 是 SharePoint 开发人员的新工具,它允许使用 lambda 表达式和流畅的接口来编写 CAML 查询。它将开发人员从 CAML 查询语法中抽离出来,帮助他们专注于业务任务。使用 Camlex.NET,开发人员可以专注于“做什么”,而不是“怎么做”。它还为 SharePoint 开发人员带来了以下优势:
- 编译时表达式检查
- 使用 lambda 表达式和流畅接口的自然直观语法
- 支持原生 .NET 类型 (
int
,string
s,bool
, DateTime ) 和操作 ( ==, !=, >, <, 等 ) - 支持 SharePoint 特定数据类型
- 能够在过滤条件中指定非常量表达式(变量、方法调用等)
- 完全可定制的结果查询对象
要开始使用 Camlex.NET,您应该从 这里 下载发行包,并在您的项目中引用 Camlex.NET.dll 程序集。之后,您就可以使用 lambda 表达式创建 CAML 查询了。
基本场景
让我们考虑一些基本场景
场景 1. 简单查询
假设您需要选择所有 Status 字段设置为 Completed 的项(以下是 CAML 的标准语法)
<Where>
<Eq>
<FieldRef Name="Status" />
<Value Type="Text">Completed</Value>
</Eq>
</Where>
可以使用 Camlex 通过以下语法创建此查询
string caml =
Camlex
.Query()
.Where(x => (string)x["Status"] == "Completed").ToString();
场景 2. 带有“and”/“or”条件的查询
假设您需要选择 ProductID = 1000 并且 IsCompleted 设置为 false 或 null 的项。以下是相应的标准 CAML 查询语法
<Where>
<And>
<Eq>
<FieldRef Name="ProductID" />
<Value Type="Integer">1000</Value>
</Eq>
<Or>
<Eq>
<FieldRef Name="IsCompleted" />
<Value Type="Boolean">0</Value>
</Eq>
<IsNull>
<FieldRef Name="IsCompleted" />
</IsNull>
</Or>
</And>
</Where>
借助 Camlex,可以使用以下自然语法进行转换
var caml =
Camlex
.Query()
.Where(x => (int)x["ProductID"] == 1000 &&
((bool)x["IsCompleted"] == false || x["IsCompleted"] == null))
.ToString();
场景 3. lvalue 和 rvalue 中带有非常量表达式的查询
非常量表达式为您提供了对 CAML 的更多控制。假设您需要根据当前区域设置选择项:对于英语区域设置,您需要选择 TitleEng 字段设置为“eng”的项;对于非英语区域设置,您需要选择 Title 字段设置为“non-eng”的项,即:
英语区域设置的查询
<Where>
<Eq>
<FieldRef Name="TitleEng" />
<Value Type="Text">eng</Value>
</Eq>
</Where>
非英语区域设置的查询
<Where>
<Eq>
<FieldRef Name="Title" />
<Value Type="Text">non-eng</Value>
</Eq>
</Where>
使用 Camlex 并不难
bool isEng = true; // or false depending on Thread.CurrentThread.CurrentUICulture
var caml =
Camlex
.Query()
.Where(x => (string)x[isEng ? "TitleEng" :
"Title"] == (isEng ? "eng" : "non-eng"))
.ToString();
内部架构
总的来说,Camlex 是 lambda 表达式到 CAML 的翻译器

它接收如下表达式
x => (int)x["ID"] == 1
作为输入,并将其翻译成有效的 CAML 查询。lambda 表达式的确切签名取决于 Camlex public
接口的方法调用。Camlex.NET 程序集中最重要的接口是 IQuery
,其实现是 Query
类
public interface IQuery
{
IQuery Where(Expression<Func<SPItem, bool>> expr);
IQuery OrderBy(Expression<Func<SPItem, object>> expr);
IQuery OrderBy(Expression<Func<SPItem, object[]>> expr);
IQuery GroupBy(Expression<Func<SPItem, object>> expr);
IQuery GroupBy(Expression<Func<SPItem, object[]>> expr,
bool? collapse, int? groupLimit);
IQuery GroupBy(Expression<Func<SPItem, object>> expr,
bool? collapse, int? groupLimit);
IQuery GroupBy(Expression<Func<SPItem, object>> expr, int? groupLimit);
IQuery GroupBy(Expression<Func<SPItem, object>> expr, bool? collapse);
XElement[] ToCaml(bool includeQueryTag);
string ToString();
string ToString(bool includeQueryTag);
}
如您所见,大多数方法都返回自身 - 因此 Camlex 支持流畅的接口调用
var caml =
Camlex
.Query()
.Where(x => x["Status"] != null)
.GroupBy(x => x["CreatedBy"])
.ToString();
同时请注意,它有一个 ToCaml()
方法,该方法以 XElement
对象数组的形式返回有效的 XML。这意味着它可以轻松定制 - 例如,您可以使用 LINQ to XML 或 System.Xml.Linq
命名空间中的类来修改结果查询。
Lambda 表达式语法
Camlex 在内部使用表达式树来解析 lambda 表达式并将其翻译成 CAML。Camlex 允许 2 种语法(此处及以下,“x”是带有 Microsoft.Sharepoint.dll 中定义的 SPItem
数据类型的 lambda 表达式的参数)
1. 原生语法
x => (int)x["ID"] == 1
即,您编写整数 rvalue 并将 lvalue 转换为 int
2. 基于字符串的语法
x => x["ID"] == (DataTypes.Integer)"1"
与原生语法相反,您将整数值写成字符串表示形式,并将其转换为 DataTypes.Integer
类(Camlex.NET.dll 中定义的辅助类)。
以上两个示例对于 Camlex 来说是等效的。我们引入了 2 种语法类型,以便不仅能够使用原生 .NET 类型(int
, string
, bool
, DateTime ),还可以使用 SharePoint 数据类型(请参阅 MSDN 链接)。您可以轻松地混合这些语法,并通过逻辑运算(&&, ||)在同一个表达式中组合它们。
以下图示显示了 Camlex 如何将带有原生类型的 lambda 表达式翻译成 CAML 查询

基于 String
的语法非常相似,除了 Camlex 使用 rvalue
转换为 DataTypes.Integer
来确定值的类型,并检查 string
表示是否包含该类型的有效值。
如果 Camlex 无法解析 lambda 表达式会发生什么?如上所述,Camlex 只支持 2 种语法类型(以及通过逻辑 && 和 || 运算的组合)。如果提供的表达式具有不同的签名,则会抛出 CamlexNET.NonSupportedExpressionException
。
下载链接
您可以从 CodeProject 或 CodePlex 下载 Camlex.NET。
额外资源
您可以在 CodePlex 上的其他场景示例、Camlex.NET 的 CodePlex 站点上的文档页面 此处,或作者的博客上找到更多信息。
历史
- 2010 年 1 月 27 日:初始版本