簡易プロバイダーのメタデータの管理

簡易プロバイダーを使用するには、メタデータを Metadata Storage Service に格納する必要があります。Metadata Storage Service は、SqlMetadataStore (マネージ コードの場合) および ISqlSyncMetadataStore (アンマネージ コードの場合) で実装されます。

メタデータ ストアには、プロバイダーやアプリケーションがやり取りする、次の種類のメタデータが格納されます。

  • レプリカ ID。特定のストアを使用するレプリカを識別します。

  • 項目 ID およびバージョン。項目ストアから列挙された各項目と、その項目の現在のバージョンを識別します。

  • 変更単位 ID およびバージョン。追跡する必要のある項目の一部と、それらの現在のバージョンを必要に応じて識別します。たとえば、連絡先データベース内の連絡先は項目であり、電話番号フィールドは変更単位の 1 つです。

項目ストアおよびメタデータ ストアにおける項目の識別

項目を同期するには、Sync Framework が項目ストアから目的の項目を識別し、その ID をメタデータ ストアにおける内部 ID に対応付けることができなければなりません。前回の同期セッション以降、項目のバージョンが変わっているかどうかを判別する機能も必要です。バージョンが変わっており、同期先レプリカに、そのバージョンの項目が存在しなかった場合、その項目を同期することになります。変更を項目レベルではなく変更単位レベルで同期する場合は、Sync Framework は、変更単位とそのバージョンを識別できる必要があります。変更単位は、連絡先を表す項目における電話番号フィールドなど、サブ項目の変更を表します。このサンプルでは変更単位を使用していません。

メタデータ ストア ID の形式の指定

次のコードでは、MyFullEnumerationSimpleSyncProvider のコンストラクターと IdFormats プロパティを定義しています。これにより、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 オブジェクトの ID ルールを作成するときは、それらの値が使用されます。

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 オブジェクトは次の 3 つのプロパティを公開しています。

  • CustomFields

    カスタム フィールドは、メタデータ ストア内で整数によって識別されます。フィールドの表示名を必要とするアプリケーションは、この整数を名前に対応付ける必要があります。カスタム フィールドが定義されるのには、2 つの理由があります。1 つは項目を識別することであり、もう 1 つは、その項目に関するバージョン情報を提供することです。Sync Framework は、バージョン フィールドによって、特定の項目または変更単位が変更済みかどうかを判断します。この例では、バージョン フィールドに、項目ストアからの実際のデータが格納されます。そのため、項目ストア内のフィールドと同じだけ、フィールドが存在することになります。このような一対一の対応は、必ずしも必要ではなく、また、決して効率的ではありません。実際には、項目フィールドのハッシュを受け取り、それを単一のカスタム フィールドに格納する方が現実的です。

  • IdentityRules

    ID ルールは、項目を識別する際に、どのカスタム フィールドを使用するかを指定します。この場合、CUSTOM_FIELD_ID フィールド (フィールド 0) が使用されます。

  • ChangeUnitVersionDefinitions (このサンプルでは不使用)

    変更単位を使用する場合は、変更単位用のバージョン フィールドを定義する必要があります。変更単位とバージョン情報とが一対一で対応している必要はなく、また、実際のデータを格納しなければならないという要件もありません。さらに、変更単位が複数のフィールドにまたがっていてもかまいません。たとえば、このアプリケーションであれば、Zip Phone を 1 つの変更単位として指定し、さらに、Guid を別の変更単位として指定することが考えられます。Guid には、実際のデータを使用し、もう 1 つの変更単位については、Zip フィールドと Phone フィールドのハッシュを使用するなど、何らかのしくみを使ってバージョンを特定することができます。

項目ストア データに作用する一部のメソッド (InsertItem など) には、個々のフィールドを表す ItemField オブジェクトのコレクションが使用されます。これらのメソッドのパラメーターである ItemFieldDictionary オブジェクトは、CustomFieldDefinition オブジェクトで指定されたものと同じインデックス値を持ちます。

参照

概念

簡易カスタム プロバイダーの実装
マネージ簡易プロバイダーを作成する方法