SharePoint Entity Framework 2 – Attributes(中文)

上一篇《介绍》叙述了如何通过FieldAttribute来将实体类属性和SharePoint列表项字段关联起来。使用FieldAttribute是一种最简单的方法,而且可以应对绝大多数使用场景。本文将会介绍FieldAttribute的其他使用方法,以及其他有助于转换的Attributes。

选项和枚举

SharePoint Entity Framework会“选项”字段转换为自定义枚举,那么就需要有一种方式来把每个候选项和自定义枚举的成员对应起来,这是通过EnumMemberAttribute来完成的。

假设SharePoint列表包含一个名为Field3的字段,类型为选项,包含三个候选项:Option #1, Option #2和Option #3。那么我们就可以编写如下的自定义枚举类型:

using WindStyle.SPEntity.Attributes;

[Flags]
public enum Choice
{
None = 0,
[EnumMember("Option #1")]
Option1 = 1,
[EnumMember("Option #2")]
Option2 = 2,
[EnumMember("Option #3")]
Option3 = 4
}

接下来我们在上一篇文章里的SampleEntity类中增加一个属性:

[Field("Field3")]
public Choice Property3 { get; set; }

如果想要读入的列表项的Field3字段值为Option #2,entity.Read方法执行结束之后,entity.Property3的值就会变成Choice.Option2。

SharePoint Entity Framework还能正确地在多值枚举和SharePoint允许多选的“选项”字段之间相互转换,如下面的代码所示:

entity.Property3 = Choice.Option1 | Choice.Option3;
entity.Write(item);
item.Update();

执行后item[“Field3”]的值会被更新为;#Option #1;#Option #3;#。

只允许读取的字段

默认情况下,所有被FieldAttribute修饰的属性都会被Entity的Read方法和Write方法处理。有时候我们会希望某字段只能被读取到属性里,而不能从属性写回。这时我们可以手工指定属性和字段的映射方式。

在SharePoint Entity Framework中,映射方式用枚举类型MappingMode来表示。它有两个成员:

  • ReadWrite:FieldAttribute采用的默认值,表示该属性既可以从字段读取值,也可以将值写入到字段中;
  • ReadOnly:表示该属性只能从字段读取值,而不可以将值写入到字段。在调用Entity.Write方法时,内部的转换机制会忽略该属性。

FieldAttribute提供Mode属性以及相应的构造函数,我们可以通过它们来指定映射方式。下面通过代码来进一步解释一下,首先在SampleEntity类中增加一个属性:

[Field("Field4", MappingMode.ReadOnly)]
public bool Property4 { get; set; }

接着将某个SharePoint列表项读入为实体,假设item[“Field4”]的值是true,那么在Read方法执行之后,entity.Property4的值也会变成true。接下来更改Property4的值并写回到item:

entity.Property4 = false;
entity.Write(item);

因为修饰Property4的FieldAttribute被指定为使用MappingMode.ReadOnly,所以Property4的值不会被写入到item,此时item[“Field4”]的值依然是true。

超链接或图片

SharePoint内置的字段中有一些拥有比较复杂的格式,字段内存储的内容可能会包含多个值,超链接或图片字段就是其中之一。在SharePoint中,超链接或图片字段的值类型为SPFieldUrlValue,其字符串表现形式为“Url,描述”。在转换时,我们可以只提取Url或描述,也可以把它们同时提取到一个自定义对象中。

这种灵活的映射方式是通过FieldAttribute的子类UrlFieldAttribute来实现的(UrlFieldAttribute及SharePoint Entity Framework中其他所有的Attribute都位于WindStyle.SPEntity.Attributes命名空间下),下面的代码描述了UrlFieldAttribute的几种使用方法:

[UrlField("Field5", UrlValue.Url)]
public Uri Property5Url { get; set; }

[UrlField("Field5", UrlValue.Description)]
public string Property5Description{ get; set; }

UrlFieldAttribute允许使用UrlValue枚举来指定想要提取的部分,UrlValue枚举包含两个成员,分别是Url和Description,分别对应于SPFieldUrlValue的两个部分值。

如果想要同时提取Url和描述,就需要编写一个自定义类型,如下面的代码所示:

public class Link
{
public string UrlAddress { get; set; }

public string Description { get; set; }
}

然后在SampleEntity中增加该类型的属性:

[UrlField("Field5", "UrlAddress", "Description")]
public Link Property5 { get; set; }

这一次使用了UrlFieldAttribute的另一个构造函数重载,分别指定了自定义类型(Link)中对应于Url和描述的属性名称。在进行转换时,SharePoint Entity Framework会按照这两个名称在自定义类型中查找相应的属性。

需要注意的是,使用UrlValue来提取部分值时,UrlFieldAttribute的映射模式会变成ReadOnly,这表示此时只允许从字段读取值,而不允许将属性的值写入到字段(因为属性的值仅仅是该字段应有值的一部分,写入的话会破坏完整性),而完整地指定了两个属性名称时则没有此限制。

UrlFieldAttribute的使用形式如下表所示:

使用形式 CLR类型 是否只允许读取
UrlField(“字段名称”, “表示Url的属性名称”, “表示描述的属性名称”) 自定义类型
UrlField(“字段名称”, UrlValue.Url) Uri, string
UrlField(“字段名称”, UrlValue.Description) string

查阅项

与超链接或图片类似,查阅项也是一个格式复杂的字段,而且其复杂程度要更胜一筹。查阅项字段的值类型为SPFieldLookupValue,其字符串形式为“Id;#值”;如果该字段允许多值,那么值类型就会是SPFieldLookupValueCollection,字符串型式是“Id1;#值1;#Id2;#值2”。

SharePoint Entity Framework提供了一个LookupFieldAttribute来关联查阅项字段和属性,使用形式和UrlFieldAttribute也很相似,只不过LookupFieldAttribute使用LookupValue枚举来指定想要提取的部分,如下表所示:

使用形式 CLR类型 是否只允许读取
LookupField(“字段名称”, “表示Id的属性名称”, “表示值的属性名称”) 自定义类型及其集合形式
LookupField(“字段名称”, LookupValue.Id) int, int[], List<int>
LookupField(“字段名称”, LookupValue.Value) string, string[], List<string>

由于查阅项字段可能包含多值,所以SharePoint Entity Framework支持将查阅项字段和一个集合类型的属性关联起来,如下面的代码所示:

[LookupField("Field6", LookupValue.Id)]
public int[] Property6Ids{ get; set; }

[LookupField("Field6", "SPListItemId", "Title")]
public SampleEntity[] Property6{ get; set; }

假设item[“Field6”]的值为“1;#One;#2;#Two”,那么执行完Read方法之后,Property6Ids的值会被更新为{1,2},而Property6的将会被更新为由两个SampleEntity对象构成的数组,这两个对象的SPListItemId属性的值分别为1和2,Title属性的值分别为One和Two。

用户或用户组

在SharePoint中,用户或用户组的值类型为SPFieldUserValue和SPFieldUserValueCollection,分别从SPFieldLookupValue和SPFieldLookupValueCollection派生而来,所以可以直接使用LookupField来将其关联到相应的属性。

除此之外,还可以直接使用FieldAttribute来将用户或用户组字段关联到一个类型为SPUser(或其集合形式)的属性,如下面的代码所示:

[Field("Field7")]
public SPUser Property7 { get; set; }

至此,我们已经介绍完了SharePoint Entity Framework对SharePoint内置字段的支持,下一篇文章将会介绍如何自定义转换逻辑以及如何支持自定义字段。

发表评论

电子邮件地址不会被公开。 必填项已用*标注