【注】之前写这张的时候前面有一章LINQ概述,涉及到了LINQ带来的一些新的语言特性,由于和SharePoint没什么关系,就不占地方了。
(二)LINQ to SharePoint
在SharePoint传统编程中进行数据查询的时候,必须使用CAML进行查询条件的编写,CAML的格式已经在本章第四节中进行过介绍。从之前的介绍中我们不难看出,作为一个XML字符串的查询,CAML在编写过程中没有任何智能感知的功能,容易出错,一旦出错之后也很难检查出来;而且CAML中所有的列表栏名称必须使用内部名称,也非常的不直观。因此在SharePoint 2003和2007时代,为了帮助开发人员更方便地编写LINQ查询,社区中提供了很多第三方的开源工具。随着SharePoint 2010中跨列表联合查询这一新特性的支持,CAML已经变得越来越复杂,即使是有经验的SharePoint开发人员,也很难快速、准确无误地写出这些复杂的列表查询。
在今天,微软将LINQ这种语言集成查询技术内置到了SharePoint 2010中,提供了LINQ to SharePoint Provider,可以在进行列表查询的时候,使用LINQ的语法特性,方便地进行查询的编写,并且支持将SharePoint列表结构转换成强类型的数据实体类,从而实现了强类型的数据查询和编译时检查。在LINQ to SharePoint Provider中,会将LINQ的查询表达式自动转换成CAML语法,进行SharePoint列表查询。同时,LINQ to SharePoint还支持对SharePoint数据的修改,可以使用强类型的数据实体,对SharePoint列表数据进行新增、修改和删除。
在SharePoint 2010中,LINQ功能提供在“Microsoft.SharePoint.Linq”命名空间中,并通过其中的DataContext类作为查询的入口。在本节的后续部分,将详细介绍LINQ to SharePoint中数据实体类的生成、使用LINQ进行SharePoint列表查询、修改的方法,以及LINQ to SharePoint在使用中的注意事项。
(三)数据实体类的生成
1、使用SPMetal命令行工具
为了能够灵活利用LINQ所带来的便捷优势,在查询的时候LINQ将通过使用强类型的数据实体类进行,如此一来可以在程序编译的时候检查其中的查询语法、字段名称是否正确,也可以让开发人员在编写程序的时候通过Visual Studio提供完善的智能感知。
在SharePoint 2010中,可以使用SPMetal工具将需要的网站、列表生成实体类。这个命令行工具放置在SharePoint前端服务器的SharePoint Root文件夹(即C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14)中的bin目录下。默认情况下,该工具需要在SharePoint前端服务器上运行。但是也可以使用“/useremoteapi”的方式运行在其他计算机上(但是功能有一定的限制,详见后文)。SPMetal使用的命令行调用形式如下:
spmetal.exe /option:value /option:value
其中可以使用的option参数包括:
参数名 | 说明 | 示例 |
web | 必选。需要生成实体类的网站的绝对路径 | /web:http://sp2010/book |
code | 生成的实体类的代码文件。 如果未指定文件扩展名,或者文件扩展名不是“cs”或“vb”,则必须由language 参数来指定生成哪种语言的代码。 该文件名还将用于生成强类型的DataContext类的名称。 | /code:Book.cs (生成的实体类的名称为BookDataContext) |
language | 用于指定生成代码的目标语言,候选项为“csharp”和“vb”。 如果使用code参数指定了生成代码文件的扩展名为“cs”或“vb”,则将忽略language参数,自动使用相应的语言来生成实体类代码文件。 | /language:csharp |
namespace | 指定生成的实体类的命名空间,如果不指定此参数,则代码编译时将使用Visual Studio项目属性中设置的默认命名空间。 | /namespace:Contoso |
useremoteapi | 使用远程访问的方式生成实体类,这使得可以在没有SharePoint的机器上运行SPMetal工具。 但需要说明的是,远程访问方式不支持列表中包含任何查阅项类型的栏。 | /useremoteapi |
user | 使用指定的用户身份访问网站,进行实体类生成(需要指定域名) | /user:contosokaneboy |
password | 当使用user参数指定特定的用户身份时,使用password参数指定该账号的密码。 | /password:Pass@word |
serialization | 指定生成的实体类是否需要支持序列化。如果此参数指定为“unidirectional”,则生成实体类的时候,会自动加入相应的串行化属性,使得这些实体类可以通过.Net的序列化机制进行自动的序列化和反序列化。 | /serialization:unidirectional |
parameters | 该参数指定生成实体类的时候,使用的配置文件。在该配置文件中,可以进一步对生成的实体类进行详细描述,可以指定需要对网站中的哪些具体列表和内容类型进行实体类的生成。 | /parameters:config.xml |
例如,使用如下的命令行为网站“http://sp2010/book”中的所有列表生成C#描述的实体类,并将命名空间指定为Contoso,代码保存在C盘根目录的Book.cs文件中:
spmetal /web:http://sp2010/book /namespace:Contoso /code:C:Book.cs
提示:如果希望进一步了解使用配置文件详细指定实体类生成规则,可以参考如下网址:http://msdn.microsoft.com/en-us/library/ee535056(v=office.14).aspx
2、自动生成的实体类的概要介绍
使用SPMetal工具生成的实体类中,主要包含如下内容:
(1) 使用DataContext的子类进行网站的描述。这个类的命名与指定使用的代码名称相关,例如“BookDataContext”,并且这个类将被声明为公开的(public)和分部类型的(partial,便于在其他代码文件中描述实体类的其他属性和方法,将数据部分于业务功能和逻辑部分分开到不同的代码文件中)。
(2) 在描述网站的DataContext类中,网站中的每一个非隐藏的列表,都会对应有一个属性(Property),以列表的名称作为属性名,其类型是EntityList泛型列表(同样来自Microsoft.SharePoint.Linq命名空间),列表所存放的类型是网站中的内容类型。
(3)网站中所使用到的列表内容类型,都会生成相应的类,以内容类型的名称作为类名,其继承关系也和内容类型的继承关系保持一致,如下图所示。内容类型所对应的类同样是声明为public和partial的。
(4) 列表中所使用到的列表栏,会生成为列表内容类型类的属性(Property),并以栏的名称作为属性名,其中常见的一些栏类型所对应的属性类型如下表所示:
栏类型 | 属性类型 | 栏类型 | 属性类型 |
单行文本 | String | 多行文本 | String |
货币 | Double | 数字 | Double |
时间和日期 | DateTime | 是/否 | Boolean |
超链接或图片 | String | 计算值 | 与计算值结果返回类型相同 |
ID | Int32 | 选项 | 枚举或字符串,详见后文 |
查阅项 | 详见后文 | 用户或用户组 | 详见后文 |
(5) 列表中的选项(单选)类型的栏,若选项栏设置中不允许用户填充新值,则会将所有候选项生成一个枚举类型;若允许用户填充,则该栏对应的属性为字符串类型,但是在栏设置中出现的候选项将生成一个字符串的常量。
(6) 列表中的选项(多选)类型的栏,若选项栏设置中不允许用户填充,而且候选项个数不超过30个,则会将所有候选项生成一个标记枚举(flag enum)类型;否则,将使用IList<String>来描述这个栏的值。
(7)列表中的单选查阅项类型的栏,会以所查阅的目标列表所对应的实体类作为其属性的类型。如果查阅项设置中开启了强制关系,还会在所查阅的目标列表的实体类中,创建相应的属性,以EntitySet类型的列表描述所有引用它的那些实体类的集合,如下图所示:
(8) 列表中的多选查阅项类型的栏,会以EntitySet类型的属性描述其所查阅的列表条目,EntitySet中使用其查阅列表所对应的内容类型实体类。
(9)用户或用户组类型的栏,将作为两个属性保存在其所在内容类型的实体类中:其中一个属性保存用户或用户组的显示名称,属性名称与栏名相同,根据是否允许多选使用IList<String>或String类型;另一个属性保存用户或用户组的Id,属性名为栏名后加“Id”,根据是否允许多选使用IList<Int32>或Int32类型。如下图所示: