簡易プロバイダーのメタデータの管理
簡易プロバイダーを使用するには、メタデータを 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 つのプロパティを公開しています。
-
カスタム フィールドは、メタデータ ストア内で整数によって識別されます。フィールドの表示名を必要とするアプリケーションは、この整数を名前に対応付ける必要があります。カスタム フィールドが定義されるのには、2 つの理由があります。1 つは項目を識別することであり、もう 1 つは、その項目に関するバージョン情報を提供することです。Sync Framework は、バージョン フィールドによって、特定の項目または変更単位が変更済みかどうかを判断します。この例では、バージョン フィールドに、項目ストアからの実際のデータが格納されます。そのため、項目ストア内のフィールドと同じだけ、フィールドが存在することになります。このような一対一の対応は、必ずしも必要ではなく、また、決して効率的ではありません。実際には、項目フィールドのハッシュを受け取り、それを単一のカスタム フィールドに格納する方が現実的です。
-
ID ルールは、項目を識別する際に、どのカスタム フィールドを使用するかを指定します。この場合、
CUSTOM_FIELD_ID
フィールド (フィールド 0) が使用されます。 ChangeUnitVersionDefinitions (このサンプルでは不使用)
変更単位を使用する場合は、変更単位用のバージョン フィールドを定義する必要があります。変更単位とバージョン情報とが一対一で対応している必要はなく、また、実際のデータを格納しなければならないという要件もありません。さらに、変更単位が複数のフィールドにまたがっていてもかまいません。たとえば、このアプリケーションであれば、
Zip
とPhone
を 1 つの変更単位として指定し、さらに、Guid
を別の変更単位として指定することが考えられます。Guid
には、実際のデータを使用し、もう 1 つの変更単位については、Zip
フィールドとPhone
フィールドのハッシュを使用するなど、何らかのしくみを使ってバージョンを特定することができます。
項目ストア データに作用する一部のメソッド (InsertItem など) には、個々のフィールドを表す ItemField オブジェクトのコレクションが使用されます。これらのメソッドのパラメーターである ItemFieldDictionary オブジェクトは、CustomFieldDefinition オブジェクトで指定されたものと同じインデックス値を持ちます。