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

Camlex.NET 2.0 for Windows SharePoint Services

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2010 年 4 月 7 日

Ms-PL

5分钟阅读

viewsIcon

23897

downloadIcon

146

Camlex.NET 2.0 为 SharePoint 开发人员带来了新的机会,例如动态筛选条件、按字段 ID 搜索等。

下载的外部链接

引言

我很高兴地宣布 Camlex.NET 项目的下一个版本已经发布。大约两个月前,我发布了 Camlex_NET。在此期间,我们收到了社区的反馈,并在 2.0 版本的工作中考虑了开发者的实际需求。几天前,Camlex.NET 2.0 发布了。在本文中,我将介绍新功能以及与前一个版本的区别。

1. 动态过滤条件

这是 2.0 版本中最令人兴奋的功能。在日常的 SharePoint 开发中,我们经常需要根据预定义的值集构建 CAML 查询。例如,我们需要搜索 ID 包含在数组 {1, 2, 3} 中的项(类似于 SQL 中的 IN 操作符),或者我们需要检索包含子字符串(或所有子字符串)的项的 Title { “hello”, “world” }。通过经典的基于字符串构建 CAML 查询的方法,这并不容易。使用 Camlex.NET 1.0 也不容易:我在其中一个 博客文章中展示了一个如何构建基于值集的动态表达式并将其传递给 Camlex 的示例。然而,这需要开发者进行额外的“基础设施”工作。所谓基础设施,我指的是与直接检索满足某些条件的项的业务任务无关的工作。在 2.0 版本中,我们解决了这个问题,并在 IQuery 接口中添加了两个新方法 WhereAllWhereAny(类似于 LINQ 中的 AllAny 方法)。

public interface IQuery
{
    IQuery Where(Expression<Func<SPListItem, bool>> expr);
    IQuery WhereAll(IEnumerable<Expression<Func<SPListItem, bool>>> expressions);
    IQuery WhereAny(IEnumerable<Expression<Func<SPListItem, bool>>> expressions);
    ...
}

Where 方法从 1.0 版本就存在了。我在这里展示它,是为了比较新方法与旧方法的签名。主要区别在于,WhereAllWhereAny 方法接收 lambda 表达式列表(或者更准确地说,是 IEnumerable),而 Where 方法接收单个 lambda 表达式。

那么这些方法做什么呢?如我所说,它们是以 LINQ 方法命名的。并且,类似于 LINQ 方法,WhereAll 方法构建 CAML 查询,用于检索满足参数中指定的所有条件的项。换句话说,WhereAll 方法使用 <And> 逻辑连接符构建 CAML 查询(参见 And element)。WhereAny 方法返回一个 CAML 查询,该查询可用于检索至少满足一个指定条件的项——它使用 <Or> 逻辑连接符(参见 Or element)。

让我们看一些例子。假设我们需要检索 Title 字段中包含 {“hello”, “greeting”, “hi”} 中至少一个值的项,即,我们需要使用以下 CAML 查询

<Where>
  <Or>
    <Or>
      <Contains>
        <FieldRef Name="Title" />
        <Value Type="Text">hello</Value>
      </Contains>
      <Contains>
        <FieldRef Name="Title" />
        <Value Type="Text">greeting</Value>
      </Contains>
    </Or>
    <Contains>
      <FieldRef Name="Title" />
      <Value Type="Text">hi</Value>
    </Contains>
  </Or>
</Where>

在 Camlex.NET 2.0 中可以这样做

// list of tokens
var tokens = new List<string> { "hello", "greeting", "hi" };
var expressions = new List<Expression<Func<SPListItem, bool>>>();

// create lambda expression for each token in list
foreach (string t in tokens)
{
string token = t;
expressions.Add(x => ((string)x["Title"]).Contains(token));
}

// prepare query
string query = Camlex.Query().WhereAny(expressions).ToString();

这个想法很简单——创建一个 lambda 表达式列表,并将这个列表传递给 Camlex。它会使用 AndOr 连接符连接表达式——因此最终会得到一个大的表达式,并将它传递给您从 1.0 版本熟悉的旧 Where 方法。

请注意,您可以创建各种表达式——也就是说,没有必要为每个值创建相同的表达式。您甚至可以在表达式中提供不同的参数名称——Camlex 不会限制您为所有提供的表达式使用相同的参数名称。例如,我们需要选择 ID = 1 Title = “Hello world” 的项

<Where>
  <And>
    <Eq>
      <FieldRef Name="ID" />
      <Value Type="Integer">1</Value>
    </Eq>
    <Eq>
      <FieldRef Name="Title" />
      <Value Type="Text">Hello world</Value>
    </Eq>
  </And>
</Where>

可以使用以下代码完成

var expressions = new List<Expression<Func<SPListItem, bool>>>();
expressions.Add(x => (int)x["ID"] == 1);
expressions.Add(y => (string)y["Title"] == "Hello world");

string query = Camlex.Query().WhereAll(expressions).ToString();

如您所见,Camlex 可以成功地翻译具有不同参数名称“x”和“y”的查询。

2. 按字段 ID 搜索

Camlex 1.0 只允许使用字段 Title 搜索项。但开发人员在准备 CAML 查询时经常使用字段 ID。在 Camlex.NET 2.0 中,现在可以使用了。让我们看看如何使用标准 Title 字段的字段 Id 来搜索 Title = “Hello world” 的项

<Where>
  <Eq>
    <FieldRef ID="fa564e0f-0c70-4ab9-b863-0177e6ddd247" />
    <Value Type="Text">Hello world</Value>
  </Eq>
</Where>

以下代码会生成此 CAML 查询

string query = Camlex.Query().Where(x => 
	(string) x[SPBuiltInFieldId.Title] == "Hello world").ToString();

SPBuiltInFieldId.Title System.Guid 类型的 OTB(开箱即用)属性。您也可以在索引器中提供您自己的 Guid 类型变量。

一个缺点是,有了这个功能,我们就失去了与 1.0 版本向后兼容性。在以前的版本中,我们在所有表达式中使用了 SPItem,它只有两个索引器,参数为 intstring。我们将 SPItem 更改为 SPListItem,它有一个额外的参数为 System.Guid 的索引器。这是 2.0 版本中的一个破坏性更改。

3. 按查找 ID 和查找值搜索

在 CAML 中,您可以使用 FieldRef 元素的未公开的 LookupId 属性来搜索项目,按查找值和查找 ID:请参阅 FieldRef Element MSDN 文章的注释。在 Camlex.NET 2.0 中也可用。例如,假设某个列表有一个“Status”查找字段,我们需要检索 Status = “Completed” 的项。我们可以使用查找值来完成

<Where>
  <Eq>
    <FieldRef Name="Status" />
    <Value Type="Lookup">Completed</Value>
  </Eq>
</Where>

或者使用查找 ID(假设具有 Title = “Completed” 的查找项的 ID = 1

<Where>
  <Eq>
    <FieldRef Name="Status" LookupId="True" />
    <Value Type="Lookup">1</Value>
  </Eq>
</Where>

对于 Camlex.NET 2.0 中的此用例,我们为 基于字符串的语法引入了两个新类型:DataTypes.LookupIdDataTypes.LookupValue。之前的 DataTypes.Lookup 已被设为内部(这是 2.0 版本中的第二次破坏性更改)。因此,上述 CAML 查询可以使用以下代码创建

// lookup value
string query = Camlex.Query().Where(
x => x["Status"] == (DataTypes.LookupValue)"Completed").ToString();

// lookup id
query = Camlex.Query().Where(
x => x["Status"] == (DataTypes.LookupId)"1").ToString();

4. 支持值的原生 System.Guid 类型

Camlex.NET 2.0 支持另一种原生类型:System.Guid。在以前的版本中,开发人员需要将 Guid 类型变量转换为 string 才能在 CAML 查询中指定 Guid 作为值(((DataTypes.Guid)val.ToString()))。现在,您可以直接将 Guid 变量传递给表达式

var guid = new Guid("a30bcb5a-c614-4dc0-8df0-8741e2aebfd9");
string query = Camlex.Query().Where(x => (Guid)x["UniqueId"] == guid).ToString();

因此,使用 Camlex.NET 2.0,您可以在索引器和值中指定 Guid。

以上是对 Camlex.NET 2.0 新功能的概述。希望它能对 SharePoint 开发有所帮助,并提高开发人员的生产力。感谢所有提供 Camlex 反馈的朋友。我们非常感谢这些努力,并希望您将来也能提供您的反馈,因为这将使我们能够使 Camlex 变得更好。

额外资源

历史

  • 2010 年 4 月 7 日:初始发布
© . All rights reserved.