管理简单提供程序的元数据

简单提供程序要求您使用元数据存储服务来存储元数据,该服务在 SqlMetadataStore(对于托管代码)和 ISqlSyncMetadataStore(对于非托管代码)中实现。

元数据存储区包含以下类型的元数据,提供程序或应用程序将与它们交互:

  • 副本 ID。它标识使用特定存储区的副本。

  • 项 ID 和版本。它们标识已从项存储区中枚举的每个项和该项的当前版本。

  • 变更单位 ID 和版本。它们可以选择标识需要跟踪的项部分和每个部分的当前版本。例如,联系人数据库中的联系人可以是项,电话号码字段可以是变更单位之一。

标识项存储区和元数据存储区中的项

要同步项,Sync Framework 必须能标识项存储区中的项并将该标识映射为元数据存储区中的内部 ID。它还必须能确定自从上一同步会话以来项版本是否发生了变更。如果版本已变更且目标副本不包含项的该版本,则应同步该项。如果是在变更单位而非项级别上同步变更,Sync Framework 必须能标识变更单位及其版本。变更单位表示子项变更,如表示联系人的项中的电话号码字段。本示例不使用变更单位。

指定元数据存储区 ID 的格式

下面的代码为 MyFullEnumerationSimpleSyncProviderIdFormats 属性定义构造函数。这使 Sync Framework 运行时可以确定元数据存储区对 ID 采用的格式。如果未使用可变 ID,Sync Framework 使用固定格式标识副本、项和变更单位。如果使用可变 ID,则使用 ISimpleSyncProviderIdGenerator 方法来生成 ID。

public MyFullEnumerationSimpleSyncProvider(string name, MySimpleDataStore store)
{
    _name = name;
    _store = store;

    // Create a file to store metadata for all items and a file to store 
    // the replica ID.
    _replicaMetadataFile = Environment.CurrentDirectory + "\\" + _name.ToString() + ".Metadata";
    _replicaIdFile = Environment.CurrentDirectory + "\\" + _name.ToString() + ".Replicaid";

    // Set ReplicaIdFormat to use a GUID as an ID, and ItemIdFormat to use a GUID plus
    // an 8-byte prefix.
    _idFormats = new SyncIdFormatGroup();
    _idFormats.ItemIdFormat.IsVariableLength = false;
    _idFormats.ItemIdFormat.Length = 24;
    _idFormats.ReplicaIdFormat.IsVariableLength = false;
    _idFormats.ReplicaIdFormat.Length = 16;

    this.ItemConstraint += new EventHandler<SimpleSyncItemConstraintEventArgs>(OnItemConstraint);
    this.ItemConflicting += new EventHandler<SimpleSyncItemConflictingEventArgs>(OnItemConflicting);
}
public SyncId ReplicaId
{
    get 
    {
        if (_replicaId == null)
        {
            _replicaId = GetReplicaIdFromFile( _replicaIdFile);
        }

        return _replicaId; 
    }
}

public override SyncIdFormatGroup IdFormats
{
    get { return _idFormats; }
}
Public Sub New(ByVal name As String, ByVal store As MySimpleDataStore)
    _name = name
    _store = store

    ' Create a file to store metadata for all items and a file to store 
    ' the replica ID. 
    _replicaMetadataFile = (Environment.CurrentDirectory & "\") + _name.ToString() & ".Metadata"
    _replicaIdFile = (Environment.CurrentDirectory & "\") + _name.ToString() & ".Replicaid"

    ' Set ReplicaIdFormat to use a GUID as an ID, and ItemIdFormat to use a GUID plus 
    ' an 8-byte prefix. 
    _idFormats = New SyncIdFormatGroup()
    _idFormats.ItemIdFormat.IsVariableLength = False
    _idFormats.ItemIdFormat.Length = 24
    _idFormats.ReplicaIdFormat.IsVariableLength = False
    _idFormats.ReplicaIdFormat.Length = 16

    AddHandler Me.ItemConstraint, AddressOf HandleItemConstraint
    AddHandler Me.ItemConflicting, AddressOf HandleItemConflicting
End Sub
Public ReadOnly Property ReplicaId() As SyncId
    Get
        If _replicaId Is Nothing Then
            _replicaId = GetReplicaIdFromFile(_replicaIdFile)
        End If

        Return _replicaId
    End Get
End Property

Public Overrides ReadOnly Property IdFormats() As SyncIdFormatGroup
    Get
        Return _idFormats
    End Get
End Property

指定项字段和元数据架构

Sync Framework 通过使用由 MetadataSchema 属性公开的 ItemMetadataSchema 对象,将项存储区数据或您创建的其他元数据映射为内部元数据存储区 ID 和版本。下面的代码示例提供了 ItemMetadataSchema 对象的输入。示例代码中的常量为项存储区中的每列定义一个整数值。当为 ItemMetadataSchema 对象创建自定义字段定义和标识值时,将使用这些值。

public const uint CUSTOM_FIELD_ID = 1;
public const uint CUSTOM_FIELD_TIMESTAMP = 2;
public override ItemMetadataSchema MetadataSchema
{
    get
    {
        CustomFieldDefinition[] customFields = new CustomFieldDefinition[2];
        customFields[0] = new CustomFieldDefinition(CUSTOM_FIELD_ID, typeof(ulong));
        customFields[1] = new CustomFieldDefinition(CUSTOM_FIELD_TIMESTAMP, typeof(ulong));

        IdentityRule[] identityRule = new IdentityRule[1];
        identityRule[0] = new IdentityRule(new uint[] { CUSTOM_FIELD_ID });

        return new ItemMetadataSchema(customFields, identityRule);
    }
}
Public Const CUSTOM_FIELD_ID As UInteger = 1
Public Const CUSTOM_FIELD_TIMESTAMP As UInteger = 2
Public Overrides ReadOnly Property MetadataSchema() As ItemMetadataSchema
    Get
        Dim customFields As CustomFieldDefinition() = New CustomFieldDefinition(1) {}
        customFields(0) = New CustomFieldDefinition(CUSTOM_FIELD_ID, GetType(ULong))
        customFields(1) = New CustomFieldDefinition(CUSTOM_FIELD_TIMESTAMP, GetType(ULong))

        Dim identityRule As IdentityRule() = New IdentityRule(0) {}
        identityRule(0) = New IdentityRule(New UInteger() {CUSTOM_FIELD_ID})

        Return New ItemMetadataSchema(customFields, identityRule)
    End Get
End Property

ItemMetadataSchema 对象公开三个属性:

  • CustomFields

    自定义字段是元数据存储区中由整数标识的字段。如果应用程序需要一个或多个字段的友好名称,应将整数映射为名称。出于两个原因定义自定义字段:标识项和提供有关这些项的版本信息。版本字段使 Sync Framework 可以确定某个项或变更单位是否已变更。在本示例中,版本字段包含项存储区的实际数据,因此项存储区中的每个字段都存在版本字段。这种一一对应不必要,而且效率不高。更实用的方法是对每个项字段进行哈希运算并将值存储在单个自定义字段中。

  • IdentityRules

    标识规则指定哪个或哪些自定义字段应该用于标识项。在本示例中,使用 CUSTOM_FIELD_ID 字段(字段 0)。

  • ChangeUnitVersionDefinitions(本示例中未使用)

    如果使用变更单位,必须定义其版本字段。在变更单位和版本信息之间不要求一定是一一对应的映射关系,也不要求必须存储实际数据。变更单位还可以跨多个字段。例如,本应用程序可以指定 Zip Phone 是一个变更单位,Guid 是另一个变更单位。对于 Guid,您可能使用实际数据,对于另一个变更单位,可能采用对 ZipPhone 字段进行哈希运算或其他机制来确定版本。

使用项存储区数据的某些方法(如 InsertItem)需要表示每个字段的 ItemField 对象的集合。作为这些方法的参数的 ItemFieldDictionary 对象必须与 CustomFieldDefinition 对象中指定的参数具有相同的索引值。

请参阅

概念

实现简单自定义提供程序
如何创建托管的简单提供程序