在列值中强制唯一性

上次修改时间: 2015年3月9日

适用范围: SharePoint Foundation 2010

本文内容
定义"唯一"
支持唯一列约束
使用唯一约束对列编制索引
以编程方式设置唯一约束
内容迁移和唯一列约束
带有列约束的"复制到"和"移动到"操作

您可以对列表或库列中的值强制实施唯一性,以便有效地创建主键。尽管以前的标识 (ID) 列是为列表或库提供唯一性的唯一方法,但 Microsoft SharePoint Foundation 2010 引入了一项名为唯一列约束 的新功能,该功能允许您强制实施唯一性。

定义"唯一"

很明显,声明唯一性并不是一件无关紧要的事,因此必须精确地定义"唯一"一词的含义。SharePoint Foundation 会计算列值,并根据它对列中的值的计算结果确定唯一性。为了进行计算,SharePoint Foundation 会使用网站 (SPWeb) 的排序顺序进行唯一性比较。请注意,这种比较不区分大小写,因此会将"hello world"和"Hello World"计算为相等。

支持唯一列约束

确定列是否支持唯一性约束的主要因素是该列是否可以编制索引。此外,当对查阅列强制实施唯一性时,目标列表中只能有一个列表项从子列表(查阅列所在的列表)查阅该列表。换句话说,不是对目标列表的投影列而是对 ID 列强制实施唯一性。下面列出了支持编制索引和不支持编制索引的列类型。

支持的列类型

下面是可以编制索引并且支持唯一列约束的列类型的列表:

  • 单行文本

  • 选项字段(不是多选)

  • 数字

  • 货币

  • 日期/时间

  • 查阅(不是多值)

  • 人员或组(不是多值)

  • 标题(不在文档库中)

不受支持的列类型

下面是不能编制索引、也不支持唯一列约束的列类型的列表:

  • 多行文本

  • 超链接/图片

  • 自定义字段类型

  • 计算字段

  • 布尔值(是/否)

  • 修改者

  • 修改时间

  • UI 版本

  • 创建时间

  • 签出目标位置

  • 内容类型 ID

使用唯一约束对列编制索引

如上所述,必须对强制实施唯一性约束的列编制索引。当用户选择"强制执行唯一值"并单击"确定"时,如果尚未对列编制索引,则会显示一个警告对话框;然后系统会向用户提供一个自动对列编制索引的选项。将列设置为强制实施唯一性后,将无法关闭该列的索引编制。不过,如果先禁止强制实施唯一性约束,则可以关闭该列的索引编制。

以编程方式设置唯一约束

SPField 对象使用 EnforceUniqueValues 属性可将列设置为需要唯一值。该属性获取并设置一个布尔值,以指定是否允许重复值;默认设置是允许重复值,因此您必须明确将列字段属性设置为 true。

以下代码示例演示了如何将字段更改为需要唯一值。请注意,在更改属性值后,必须明确更新该字段。

SPSite site = new SPSite("https://localhost");
SPWeb web = site.OpenWeb();

SPList custList = web.Lists["Customers"];
SPField custPhone = custList.Fields["Phone Number"];

custPhone.Indexed = true;
custPhone.EnforceUniqueValues = true;

/// You must call the Update() method 
/// when you change the EnforceUniqueValues property
custPhone.Update();

错误情形 - 异常

有两种与使用 EnforceUniqueValues 属性强制实施唯一性相关联的错误情形:

  • 针对未编制索引的字段设置 EnforceUniqueValues = true。
    引发异常对象 (SPException),并出现消息"必须先对字段编制索引才能强制实施唯一性。"

  • 对已经具有重复值的列表设置 EnforceUniqueValues = true。
    引发异常对象 (SPException),并出现消息"此字段包含重复值。删除所有重复值并重试操作。"

内容迁移和唯一列约束

Microsoft.SharePoint.Deployment 命名空间中使用 API 进行的内容迁移支持通过使用导出/导入功能来实现部分(选择性)和完整网站集迁移。在完整迁移方案中使用部署 API 时,必须确保如果对导出源上的列表字段设置了唯一性属性(即,EnforceUniqueValues 属性设置为 true),则导入目标上必须存在该设置。

但是,在执行部分(选择性)迁移时,会将源网站集的文件与目标上的文件进行合并,因此该操作将自动决定唯一性状态,如此处所述。

源上的列唯一,目标上的列不唯一

  1. 项目被导入目标位置或目标。

  2. 然后,将目标上的 EnforceUniqueValues 属性设置为 true。

请注意,如果目标上的列表中存在重复项,从而违反唯一性约束,则该操作可能会失败。如果出现这种情况,将不会设置唯一性属性值,并且该尝试将返回非致命错误。

源上的列唯一,目标上的列也唯一

按通常方式对列表执行导出/导入。

如果导入包中的项违反了唯一性约束,则该操作将会失败。如果出现这种情况,将不会导入该项,并且该尝试将返回非致命错误。

源上的列不唯一,目标上的列唯一

  1. 首先,通过将目标上的 EnforceUniqueValues 属性设置为 false 来禁用目标列表上的字段的唯一性。

  2. 按通常方式将列表项导入目标。

备注

如果在导入时使用 RetainObjectIdentity 属性,则也会发生上面列出的三种情形。在这种情况下,将不会导入目标上的重复项,而是更新目标上已存在的项,使其与从源导出的项相匹配。

带有列约束的"复制到"和"移动到"操作

每次将项复制或移动到强制实施唯一列约束的文档库,并且使用 SPFile 类上的 CopyTo(String)MoveTo(String) 方法执行这些操作时,都需要考虑一些特殊的注意事项。在将文件移动或复制到此类库时,必须清楚这一点。

由于在 MoveTo() 方案中可能会丢失数据,而在 CopyTo() 方案中可以大大降低这种可能性(因为不会删除源中的文件),因此,应遵循的一般规则是在 MoveTo() 操作中禁止唯一列约束,而在 CopyTo() 操作中允许唯一列约束。以下列表详细描述了相关规范:

Copy To operation

Move To operation

在同一文档库内

检查文档级别的唯一性违规情况。不跨库文件夹进行检查。

移动而不进行检查。

跨文档库

将值转换为 null。

如果目标位置列表已实施了唯一值,则阻止移动。

移出文档库

没有影响。

没有影响。

移入文档库

将值转换为 null。

将值转换为 null。

请参阅

引用

EnforceUniqueValues

RetainObjectIdentity

SPFile.CopyTo(String)

SPFile.MoveTo(String)