65.9K
CodeProject 正在变化。 阅读更多。
Home

Camlex.NET for Windows SharePoint Services

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (3投票s)

2010年1月28日

Ms-PL

4分钟阅读

viewsIcon

32112

downloadIcon

262

Camlex.NET 通过使用表达式树简化了 Windows SharePoint Services 的 CAML 查询创建过程

引言

Camlex.NET ( http://camlex.codeplex.com ) 是 SharePoint 开发人员的新工具,它允许使用 lambda 表达式和流畅的接口来编写 CAML 查询。它将开发人员从 CAML 查询语法中抽离出来,帮助他们专注于业务任务。使用 Camlex.NET,开发人员可以专注于“做什么”,而不是“怎么做”。它还为 SharePoint 开发人员带来了以下优势:

  • 编译时表达式检查
  • 使用 lambda 表达式和流畅接口的自然直观语法
  • 支持原生 .NET 类型 ( int, strings, 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

下载链接

您可以从 CodeProjectCodePlex 下载 Camlex.NET。

额外资源

您可以在 CodePlex 上的其他场景示例、Camlex.NET 的 CodePlex 站点上的文档页面 此处,或作者的博客上找到更多信息。

历史

  • 2010 年 1 月 27 日:初始版本
© . All rights reserved.