同期データのフィルター設定
同期するデータを制限するにはフィルターを使用します。通常、同期元プロバイダーは、変更の列挙中にフィルターを適用して送信する変更を制限します。Sync Framework は次の種類のフィルターをサポートしています。
項目フィルター: 同期対象のデータを一部の項目に限定します。たとえば、2 つのファイル フォルダー間で .txt ファイルだけを同期し、他の種類のファイルは無視する場合などに使用します。どのような変更が項目に加えられたとしても、既存の項目の一致状態 (フィルター条件に一致するかどうか) が変化することはありません。項目フィルターの使用は容易ですが、同期に使用されるメタデータは、同期スコープ内の項目数に比例して増加します。
変更単位フィルター: 同期対象のデータを一部の変更単位に限定します。たとえば、連絡先の name フィールドと phone number フィールドだけを同期し、その他の変更単位は無視する場合などに使用します。
カスタム フィルター: Sync Framework にとって既知であるかどうかという観点で同期データを制限します。カスタム フィルターには、項目が徐々に追加または除外されていく可能性があります。Sync Framework はメタデータの全体サイズを小さく抑えながら、カスタム フィルターを効率的にサポートする追加のメタデータ、インターフェイス、およびクラスを定義します。
フィルターは同期アプリケーションまたは同期元/同期先プロバイダーで定義できるほか、同期元プロバイダーと同期先プロバイダーの間でネゴシエートすることもできます。
フィルターは、同期元プロバイダーが変更を検出するときに使用されます。変更の検出時に構築される変更バッチには、フィルター条件を満たした同期データだけが追加されます。
フィルターは、同期先プロバイダーが変更を適用するときにも使用されます。同期先レプリカに適用される変更には、フィルター条件を満たした同期データだけが含まれます。
同期対象の項目の制御
項目フィルターは、変更の列挙時に同期元プロバイダーから送信される項目変更を定義します。項目のフィルター方法は同期スコープに含まれるデータの種類によって異なるので、Sync Framework では、フィルター選択のメカニズムを同期元プロバイダーが定義できるようになっています。プロバイダーと同期アプリケーション間でフィルターについてのやり取りが必要な場合も、適切なメカニズムを自由に使って実現できます。
Sync Framework の要件上、項目の変更をフィルター選択する場合、同期元プロバイダーが、変更の列挙中に送信されるすべての変更バッチ オブジェクトに対し、フィルターに関する情報を関連付ける必要があります。Sync Framework は変更バッチ オブジェクトに項目フィルター情報が存在するのを見て、フィルターを使った同期が実行されようとしていることを察知します。こうして Sync Framework は、フィルター選択された変更バッチのナレッジを正しく処理できます。同期元プロバイダーが変更バッチに含まれる項目をフィルター選択する場合、変更バッチ オブジェクトに項目フィルター情報が指定されていないと、Sync Framework はナレッジを正しく処理できません。
同期元プロバイダーが、変更バッチに含まれる項目を制限するフィルターを使用する場合、プロバイダーはフィルターに関する情報を ChangeBatch (マネージ コードの場合) または ISyncChangeBatch (アンマネージ コードの場合) オブジェクトに関連付ける必要があります。フィルター情報は、ItemListFilterInfo オブジェクト (マネージ コードの場合) または SYNC_FILTER_INFO_FLAG_ITEM_LIST フラグが設定された ISyncFilterInfo オブジェクト (アンマネージ コードの場合) によって表されます。アンマネージ コードの場合、プロバイダーは IProviderFilteredSyncServices::CreateFilterInfo を使用して、ISyncFilterInfo オブジェクトを作成します。フィルター情報を変更バッチに関連付けるには、ChangeBatch (マネージ コードの場合) または IProviderFilteredSyncServices::CreateFilteredEnumerationChangeBatch (アンマネージ コードの場合) を使用して変更バッチ オブジェクトを作成します。
項目のフィルター選択の使用方法の詳細については、「列挙された項目をフィルターする方法」を参照してください。
同期対象の変更単位の制御
変更単位フィルターは、変更の列挙時に同期元プロバイダーから送信される各項目変更に、どの変更単位の変更を追加するかを定義します。スコープ内の項目に定義されている変更単位の一部分だけをレプリカに保存するような場合、変更単位フィルターが効果的です。
たとえば、同期コミュニティは連絡先情報を交換し、name、phone number、および address の変更単位を定義します。コミュニティ内のレプリカの 1 つは、name と phone number だけを格納できるモバイル デバイスです。このレプリカは、変更単位フィルターを使用して、この 2 つの変更単位のナレッジのみを追跡するように指定します。同期元レプリカは、デバイスのレプリカとの間でデータを同期する際、変更単位フィルターを使用して name および phone number の変更単位についてのみ情報を送信します。同期元プロバイダーから学習したナレッジは、デバイス レプリカのナレッジに name と phone number の変更単位のみのナレッジが格納されるよう、変更単位フィルターに射影されます。同様に、デバイスに対してローカルに変更が加えられ、以降、そのデバイスが同期セッションにおける同期元レプリカとして機能する場合、変更を受け取るレプリカは、指定された一連の変更単位についてのみそのナレッジを更新します。
変更単位フィルターを使用した場合、Sync Framework は、変更バッチに関する学習したナレッジに、指定された変更単位についての情報だけが格納されるよう、変更バッチに関する学習したナレッジを、フィルターによって指定された一連の変更単位に射影します。
変更単位の変更をフィルター選択するには、同期元プロバイダーで ChangeUnitListFilterInfo オブジェクト (マネージ コードの場合) または IChangeUnitListFilterInfo (アンマネージ コードの場合) を作成し、同期対象の一連の変更単位を指定します。アンマネージ コードの場合、IChangeUnitListFilterInfo オブジェクトは、IProviderFilteredSyncServices::CreateFilterInfo メソッドに SYNC_FILTER_INFO_FLAG_CHANGE_UNIT_LIST を指定することによって作成します。同期元プロバイダーは、ChangeBatch (マネージ コードの場合) または IProviderFilteredSyncServices::CreateFilteredEnumerationChangeBatch (アンマネージ コードの場合) を使用してフィルター情報を変更バッチに関連付け、変更バッチ オブジェクトを作成します。
変更単位フィルターの使用方法の詳細については、「列挙された変更単位をフィルター選択する方法」を参照してください。
カスタム フィルターを使用した同期対象の制御
カスタム フィルターは Sync Framework の外で、通常はプロバイダー開発者によって定義されますが、サード パーティで定義することも可能です。Sync Framework には、同期スコープに含める対象がフィルターによってどのように決定されるのかを知る手段がありません。カスタム フィルターは、項目が徐々に追加または除外されるような形での定義が可能です。たとえば、メディア ファイルを格納するレプリカに対して、三つ星以上と評価されたすべてのファイルを含めるようなフィルターを定義できます。ファイルに対するユーザー評価が変更されると、そのファイルがフィルターに追加されることもフィルターから除外されることもあります。
簡易プロバイダー、または制約の競合を報告したり変更適用サービスを利用したりするプロバイダーではカスタム フィルターを使用できないことに注意してください。このようなプロバイダーでカスタム フィルターを使用すると、予期しない結果が生じる可能性があります。
カスタム フィルターを効率的にサポートするために、Sync Framework では新しい概念がいくつか定義されています。
フィルター追跡レプリカは、現在追跡フィルターに含まれる項目および変更単位と、最近追跡フィルターに追加された、または追跡フィルターから除外された項目および変更単位を定義したメタデータを管理するレプリカです。さらにこのメタデータでは、追跡フィルターに含まれずに忘れられたすべての項目と変更単位を対象とした、フィルターの忘れられたナレッジも定義されます。フィルターの追跡は、どんな項目がレプリカに格納されるかということには影響しません。レプリカでは、すべての項目を同期スコープに格納しながら同時に複数のフィルターを追跡できます。通常、フィルター追跡レプリカは、フィルターされた変更バッチを追跡対象のフィルターに提供できます。
フィルターされたレプリカは、フィルターに含まれている項目と変更単位のみに対して項目と変更単位のデータを格納し、フィルターに含まれていたが除外された項目および変更単位に対してメタデータを格納するレプリカです。フィルターされたレプリカは使用するフィルターを常に追跡しますが、追加のフィルターも追跡することがあります。フィルターされた同期先プロバイダーは、フィルターされた変更の列挙を同期元プロバイダーから要求することも、完全な変更の列挙を要求し、変更適用時にその変更を自身でフィルターすることもできます。
非実体はフィルター内に存在したものの除外された、フィルターされたレプリカ内の項目または変更単位です。フィルターされたレプリカでは、非実体のメタデータは格納されますが、項目や変更単位データは格納されません。
フィルターの忘れられたナレッジはフィルター追跡の起点を定義します。フィルター追跡レプリカでは、非実体を削除し、フィルターの忘れられたナレッジを進めて削除された非実体の最大バージョンを含めることによって、ストレージ領域を節約することができます。同期コミュニティの他のレプリカでフィルターが使用された後にレプリカがそのフィルターの追跡を開始した場合には、フィルターの忘れられたナレッジも使用されます。
フィルターの追跡
同期コミュニティのすべてのレプリカで、コミュニティで使用されているフィルターを追跡することをお勧めします。フィルターされたレプリカがフィルター追跡レプリカからフィルターされた変更の列挙を受け取る場合、フィルターされたレプリカのナレッジは小さく抑えることができます。フィルターされたレプリカがフィルターを追跡しないレプリカからフィルターされた変更の列挙を受け取る場合、ナレッジのサイズは送信された変更の数に比例して大きくなります。
フィルターの追跡の詳細については、「フィルターを追跡し、フィルターされた変更を列挙する方法」を参照してください。
フィルター メタデータ
フィルターを追跡するために、レプリカはレプリカ内の各項目または変更単位のフィルター メタデータを保管します。フィルター メタデータには、次の表の要素が含まれています。
フィルターに含まれるかどうか | 移動バージョン |
---|---|
項目または変更単位がフィルターに含まれるかどうかを示します。 |
項目がフィルターに追加またはフィルターから除外される原因となった変更バージョンです。項目が作成されてフィルターに追加されると、このバージョンが項目の作成バージョンに設定されます。項目がフィルターに追加されていない場合、このバージョンは (0,0) に設定されます。 |
レプリカがフィルターの追跡を開始した場合、すべての項目または変更単位をフィルターに対して評価する必要があります。項目または変更単位がフィルター内に存在する場合は、それがフィルター内に存在することをフィルターのメタデータで示し、移動バージョンをその項目または変更単位の最新変更バージョンに設定する必要があります。項目がフィルター内に存在しない場合は、そのフィルター メタデータで項目がフィルターに存在しないことを示し、移動バージョンを (0,0) に設定する必要があります。
フィルター追跡レプリカには、そのレプリカで追跡する各フィルターに関する、フィルターの忘れられたナレッジも格納できます。フィルター追跡レプリカがフィルターの発生時からそのフィルターを追跡していても、フィルターを追跡しないレプリカから同期データを受け取らなければ、フィルターの忘れられたナレッジは格納されません。フィルターの発生後しばらくしてからフィルター追跡レプリカがそのフィルターの追跡を開始する場合は、フィルターの忘れられたナレッジをレプリカの現在のナレッジに初期設定する必要があります。廃棄標識とフィルター変更メタデータがレプリカでクリーン アップされた場合、フィルターの忘れられたナレッジを破棄し、忘れられたナレッジを代わりに使用することができます。
追跡されるフィルターのネゴシエーション
フィルター追跡プロバイダーは IFilterTrackingProvider (マネージ コードの場合) または IFilterTrackingProvider (アンマネージ コードの場合) を実装する必要があります。このインターフェイスは、同期元レプリカと同期先レプリカの両方で追跡されるフィルターのデータのやり取りのために使用されます。同期元レプリカは同期元レプリカと同期先レプリカの両方で追跡されるフィルターのフィルター メタデータを送信します。
同期セッションの両方のプロバイダーがフィルター追跡プロバイダーである場合、Sync Framework は両方のプロバイダーでどのフィルターを追跡するかを決めるネゴシエーションを仲介します。追跡されるフィルターのネゴシエーションは、2 つのフィルター追跡プロバイダー間で、次の手順を使用して行われます。
BeginSession (マネージ コードの場合) または IKnowledgeSyncProvider::BeginSession (アンマネージ コードの場合) を呼び出した後、Sync Framework は同期先プロバイダーの SpecifyTrackedFilters (マネージ コードの場合) または IFilterTrackingProvider::SpecifyTrackedFilters (アンマネージ コードの場合) を呼び出します。
同期先プロバイダーは追跡されるフィルターの一覧を列挙し、RequestTrackedFilterCallback デリゲート (マネージ コードの場合) または SpecifyTrackedFilters への呼び出しで指定された IFilterRequestCallback オブジェクトの IFilterRequestCallback::RequestFilter メソッド (アンマネージ コードの場合) に、それぞれのフィルターを渡します。
同期先プロバイダーで指定された各フィルターについて、Sync Framework は同期元プロバイダーの TryAddTrackedFilter (マネージ コードの場合) または IFilterTrackingProvider::AddTrackedFilter (アンマネージ コードの場合) を呼び出します。
同期元プロバイダーは同期先プロバイダーによって追跡されるフィルターの一覧を管理し、指定のフィルターを追跡するかどうかを示す値を返します。
Sync Framework はこの値を同期先プロバイダーに渡します。
追跡されるフィルターのフィルター メタデータの送信
同期元プロバイダーでも追跡されるフィルターを同期先プロバイダーが追跡する場合、同期元プロバイダーは双方で追跡するフィルターのフィルター メタデータを送信する必要があります。この処理を行うには、GetChangeBatch (マネージ コードの場合) または IKnowledgeSyncProvider::GetChangeBatch (アンマネージ コードの場合) の同期元プロバイダー実装に、次の変更を加えます。
FilterKeyMap プロパティを設定することで FilterKeyMap オブジェクトを ChangeBatch オブジェクトに追加する (マネージ コードの場合) か、ISyncChangeBatchWithFilterKeyMap::SetFilterKeyMap を呼び出すことで IFilterKeyMap オブジェクトを ISyncChangeBatchWithFilterKeyMap オブジェクトに追加します (アンマネージ コードの場合)。フィルター キー マップ オブジェクトには、同期元プロバイダーと同期先プロバイダーの両方で追跡されるフィルターが格納されます。変更バッチのグループを開始する前に、FilterKeyMap プロパティを設定する (マネージ コードの場合) か、SetFilterKeyMap メソッドを呼び出す必要があります (アンマネージ コードの場合)。
変更バッチのグループごとに、SetFilterForgottenKnowledge (マネージ コードの場合) か ISyncChangeBatchWithFilterKeyMap::SetFilterForgottenKnowledge (アンマネージ コードの場合) を呼び出して、追跡されるフィルターの忘れられたナレッジを追加します。
追跡されるフィルターに追加された、またはフィルターから除外された各項目または変更単位について、フィルター変更を送信します。フィルター変更メタデータは、AddFilterChange (マネージ コードの場合) または IFilterTrackingSyncChangeBuilder::AddFilterChange (アンマネージ コードの場合) を呼び出すことによって変更に追加されます。FilterChange プロパティ (マネージ コードの場合) または SYNC_FILTER_CHANGE (アンマネージ コードの場合) の値は、項目がフィルターに追加されたか、フィルターから除外されたかを示すと共に、その移動の原因となった変更のバージョンを示します。フィルター変更メタデータは、項目の同期先ナレッジに移動バージョンが含まれていない場合にのみ追加されます。変更単位を使用するとき、移動バージョンが変更単位の同期先ナレッジに含まれていない場合は、フィルター変更メタデータを追加する必要があります。移動バージョンは変更単位を使用する場合でも項目バージョンとして扱われるため、含まれているかどうかを確認するには、変更単位バージョンではなく項目バージョンを受け取る形式の Contains メソッド (マネージ コードの場合) または ISyncKnowledge::ContainsChange メソッド (アンマネージ コードの場合) を使用する必要があります。
変更単位を使用したときに少なくとも 1 つの変更単位の変更が同期先ナレッジに含まれていない場合は、所有側項目の AllChangeUnitsRequired と項目 ID (マネージ コードの場合) または所有側項目の項目 ID (アンマネージ コードの場合) を指定して、同期先ナレッジの ContainsMarker (マネージ コードの場合) または IKnowledgeWithMarkers::ContainsAllChangeUnitsRequiredMarker (アンマネージ コードの場合) を呼び出します。このメソッドですべての変更単位が必要であると示された場合、項目のすべての変更単位を送信し、ItemChange オブジェクト (マネージ コードの場合) または IFilterTrackingSyncChangeBuilder::SetAllChangeUnitsPresentFlag (アンマネージ コードの場合) で SetAllChangeUnitsPresent を呼び出します。
フィルターされた変更の送信
通常、フィルター追跡レプリカを表す同期元プロバイダーは、追跡されるフィルターについて、フィルターされた変更バッチを列挙できます。フィルターは、アプリケーションと同期元プロバイダーの間のカスタム メカニズムを使用してアプリケーションで識別することも、同期元プロバイダーと同期先プロバイダーの間のネゴシエーションによって決定することもできます。フィルターのネゴシエーションについては、このドキュメントの後半で説明します。
フィルターされた変更バッチを送信するには、同期元プロバイダーの GetChangeBatch メソッドに次の要素を追加します。
同期に使用するフィルターが含まれる CustomFilterInfo (マネージ コードの場合) または ICustomFilterInfo (アンマネージ コードの場合) オブジェクトを作成します。フィルター情報オブジェクトを適切な変更バッチ コンストラクター ChangeBatch に渡す (マネージ コードの場合) か、IProviderFilteredSyncServices::CreateFilteredEnumerationChangeBatch (アンマネージ コードの場合) を呼び出すことで、フィルターされた変更バッチ オブジェクトを作成します。また、変更バッチ オブジェクトを作成する際に、レプリカの忘れられたナレッジではなく、フィルターの忘れられたナレッジを渡します。
以前は項目または変更単位がフィルターに存在したが、現在は存在しない場合は、ChangeKind プロパティを Ghost に指定する (マネージ コードの場合) か、SYNC_CHANGE_FLAG_GHOST フラグを ISyncChangeBatchBase::AddItemMetadataToGroup に渡します (アンマネージ コードの場合)。
同期先プロバイダーのフィルター選択の種類が CurrentItemsOnly (マネージ コードの場合) または FT_CURRENT_ITEMS_ONLY (アンマネージ コードの場合) であれば、フィルター内にある場合にのみ項目を変更バッチに含めます。つまり、非実体は送信しません。
同期先プロバイダーのフィルター選択の種類が CurrentItemsAndVersionsForMovedOutItems (マネージ コードの場合) または FT_CURRENT_ITEMS_AND_VERSIONS_FOR_MOVED_OUT_ITEMS (アンマネージ コードの場合) であれば、フィルター内に存在する項目と除外された項目を含めます。項目または変更単位が以前にフィルター内に存在し、項目または変更単位が現在フィルター内に存在せず、項目または変更単位をフィルターから除外した変更のバージョンが同期先ナレッジに含まれていない場合には、除外情報を送信する必要があります。
フィルター メタデータの適用
同期先プロバイダーがフィルター追跡プロバイダーを表し、変更適用元を使用して同期先レプリカに変更を適用する場合、同期先プロバイダーは IFilterTrackingNotifyingChangeApplierTarget (マネージ コードの場合) または IFilterTrackingNotifyingChangeApplierTarget (アンマネージ コードの場合) を実装する必要があります。このインターフェイスには、追跡されるフィルターのフィルター キー マップおよびフィルターの忘れられたナレッジを取得するために Sync Framework が使用するメソッドが含まれています。また、Sync Framework がフィルター追跡プロバイダーのために StoreKnowledgeForScope (マネージ コードの場合) または ISynchronousNotifyingChangeApplierTarget::SaveKnowledge (アンマネージ コードの場合) の代わりに呼び出す SaveKnowledgeWithFilterForgottenKnowledge (マネージ コードの場合) または IFilterTrackingNotifyingChangeApplierTarget::SaveKnowledgeWithFilterForgottenKnowledges (アンマネージ コードの場合) メソッドも含まれています。Sync Framework はこのメソッドを使用して、変更バッチの適用後に更新されたナレッジ、忘れられたナレッジ、およびフィルターの忘れられたナレッジをプロバイダーに送信します。
IFilterTrackingNotifyingChangeApplierTarget の実装に加えて、同期先プロバイダーの SaveItemChange または SaveChangeWithChangeUnits メソッド (マネージ コードの場合)、あるいは ISynchronousNotifyingChangeApplierTarget::SaveChange または ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits メソッド (アンマネージ コードの場合) を更新し、次の手順を実行する必要があります。
変更オブジェクトの GetFilterChange (マネージ コードの場合) または ISyncChangeWithFilterKeyMap::GetFilterChange (アンマネージ コードの場合) を呼び出して、追跡される各フィルターのフィルター変更メタデータを取得します。
フィルター変更メタデータが存在する場合は、それが期限切れでないことを確認してください。フィルター変更の移動バージョンが項目の同期先ナレッジに含まれている場合、そのフィルター変更は期限切れです。変更単位を使用するとき、移動バージョンがすべての変更単位の同期先ナレッジに含まれている場合にのみフィルター変更は期限切れです。期限切れのフィルター変更は同期先レプリカに適用しないでください。
期限切れでないフィルター変更メタデータが存在する場合は、データが同期先レプリカに存在するフィルター変更情報と競合していないことを確認してください。競合を確認するには、次の手順を実行します。
同期先レプリカの項目または変更単位に現在格納されている移動バージョンを取得します。
移動バージョンが項目に関連付けられているナレッジに含まれているか、項目に関連付けられた各変更単位に関連付けられているナレッジに含まれているかを確認します。
関連付けられている適切なナレッジに移動バージョンが含まれていない場合、フィルター変更は競合しています。同期先プロバイダーは必要に応じてこれを解決し、新しい移動バージョンを変更に割り当てる必要があります。
移動バージョンで競合が検出されなかった場合、同期元フィルター変更の移動フラグを、同期先項目または変更単位の移動フラグと照合します。フラグの値が一致しなかった場合、同期先プロバイダーでは、フィルターに対して項目または変更単位を評価し、新しい移動バージョンと共に正しい移動フラグの値を割り当てる必要があります。
どのような競合も検出されなかった場合は、項目のメタデータと一緒にフィルター変更メタデータを保管します。
追跡されるフィルターのフィルター変更メタデータがない場合、または同期元レプリカではなく同期先レプリカによって追跡されるフィルターのフィルター変更メタデータがない場合、変更を同期先のフィルターに対して評価します。フィルター メタデータを更新して、項目がフィルター内に存在するかどうかを示す情報を含めます。変更によって項目がフィルターに追加された場合またはフィルターから除外された場合は、移動バージョンを変更のバージョンに更新します。複数の変更単位が 1 つのフィルターに関連付けられていて、それらのフィルターに対する変更によって項目がフィルターに追加される場合またはフィルターから除外される場合は、新しいローカル バージョンを作成して、項目の移動バージョンおよびフィルターに関連付けられた変更単位のすべての変更バージョンとして割り当てます。
フィルターされたレプリカ
フィルターされたレプリカには、フィルターに含まれている項目と変更単位のみに対して項目と変更単位のデータが格納され、フィルターに含まれていたが除外された項目と変更単位のメタデータである非実体も格納されます。フィルターされたレプリカはそのフィルターを追跡しますが、他のフィルターも追跡することがあります。フィルターされたレプリカは同期元プロバイダーとの間でフィルターに関するネゴシエーションを行うことができます。その場合、同期元プロバイダーはフィルターされた変更バッチを作成します。同期元プロバイダーでフィルターされた変更バッチを作成できない場合、フィルターされたプロバイダーは独自に変更をフィルターし、フィルター内に存在する変更のみを適用します。
フィルターされたレプリカの実装の詳細については、「レプリカをフィルターする方法」を参照してください。
フィルターに追加された項目の列挙
フィルターされたレプリカには、IFilteredReplicaNotifyingChangeApplierTarget (マネージ コードの場合) または IFilteredReplicaNotifyingChangeApplierTarget (アンマネージ コードの場合) インターフェイスが実装されます。このインターフェイスには GetNewMoveInItems (マネージ コードの場合) または IFilteredReplicaNotifyingChangeApplierTarget::GetNewMoveins (アンマネージ コードの場合) が含まれており、Sync Framework はこれを使用して特定の時点より後にフィルターに追加された項目を取得します。項目がこのメソッドから返される一覧に追加されるのは、その項目がアクティブであり、フィルター内に存在し、項目の移動バージョンがメソッドで指定されたナレッジに含まれていない場合です。
フィルター選択されなかった変更の送信
フィルターされたレプリカが同期元レプリカであり、フィルターされた変更の列挙が同期先レプリカで要求されない場合、または 2 つのレプリカ間でのフィルターのネゴシエーションが正常に終了しない場合は、同期元レプリカはフィルターされていない場合と同様に変更を列挙します。これは、フィルターされた変更の送信の処理と次の点で異なります。
フィルター選択されなかった変更バッチが作成されます。
変更バッチが作成されると、フィルターされた変更が送信されるときのようなフィルターの忘れられたナレッジではなく、レプリカの忘れられたナレッジが渡されます。
フィルター選択された変更の適用
同期先プロバイダーが変更適用元を使用して変更を適用した場合、同期先バージョンを変更適用元に送信するときに同期先項目または変更単位が非実体かどうかを指定する必要があります。この操作を実行するには、同期先レプリカでその項目が非実体である場合に、ChangeKind プロパティに Ghost を指定するか (マネージ コードの場合)、SYNC_CHANGE_FLAG_GHOST フラグを IDestinationChangeVersionsBuilder::AddItemMetadata に渡します (アンマネージ コードの場合)。項目が非実体になるのは、同期先メタデータ ストアに項目のメタデータが存在し、項目が削除されておらず、同期先ストアに項目のデータが存在しない場合です。
同期元プロバイダーの変更がフィルターされていない場合、同期先プロバイダーは同期元プロバイダーによって送信されたすべての変更を同期先レプリカのフィルターに対して評価します。同期先プロバイダーはフィルターを通過した変更を適用し、影響がある非実体を更新します。同期先プロバイダーは、スキップされた変更を変更バッチのナレッジから除外します。
同期先プロバイダーは、自身の SaveItemChange または SaveChangeWithChangeUnits メソッド (マネージ コードの場合)、あるいは ISynchronousNotifyingChangeApplierTarget::SaveChange または ISynchronousNotifyingChangeApplierTarget::SaveChangeWithChangeUnits メソッド (アンマネージ コードの場合) にも、次の変更を加える必要があります。
非実体のメタデータを作成または更新することにより、CreateGhost および UpdateGhost アクション (マネージ コードの場合)、あるいは SSA_CREATE_GHOST または SSA_UPDATE_GHOST アクション (アンマネージ コードの場合) を処理します。場合によっては、フィルター変更メタデータも更新する必要があります。
項目または変更単位のデータを削除し、変更が反映されるように項目または変更単位のメタデータを更新することによって、MarkItemAsGhost アクション (マネージ コードの場合) または SSA_GHOST_ITEM アクション (アンマネージ コードの場合) を処理します。
項目または変更単位のデータを取得し、そのデータを同期先レプリカに格納して、変更が反映されるようにメタデータを更新することにより、UnmarkItemAsGhost アクション (マネージ コードの場合) または SSA_UNGHOST_ITEM アクション (アンマネージ コードの場合) を処理します。
非実体のメタデータに削除のマークを付けることにより、DeleteGhostAndStoreTombstone アクション (マネージ コードの場合) または SSA_DELETE_GHOST_AND_STORE_TOMBSTONE アクション (アンマネージ コードの場合) を処理します。
非実体のクリーンアップ
フィルターされたレプリカのストレージ領域を解放するには、非実体を削除することができます。非実体を削除したら、フィルターの忘れられたナレッジの ForgetTo メソッド (マネージ コードの場合) または IForgottenKnowledge::ForgetToVersion メソッド (アンマネージ コードの場合) に非実体の移動バージョンを渡すことによって、フィルターの忘れられたナレッジを更新する必要があります。
フィルターのネゴシエーション
変更の列挙時に同期元プロバイダーによって使用されるフィルターは、同期先プロバイダーが同期元プロバイダーに対して指定することができます。同期元プロバイダーは、同期先プロバイダーから要求されたフィルターを受け入れることも、拒否することもできます。同期先プロバイダーは、同期元プロバイダーによって承認されるフィルターが見つかるまで、異なるフィルターを要求できます。このネゴシエーションは Sync Framework の仲介の下で行われます。これによってプロバイダーに最も適した種類のフィルターが選択されます。
フィルターのネゴシエーションに参加するには、同期元プロバイダーは ISupportFilteredSync (マネージ コードの場合) または ISupportFilteredSync (アンマネージ コードの場合) を実装し、同期先プロバイダーは IRequestFilteredSync (マネージ コードの場合) または IRequestFilteredSync (アンマネージ コードの場合) を実装する必要があります。
フィルターのネゴシエーションは次の手順で行われます。
同期元プロバイダーで変更の列挙を開始する前、かつ BeginSession (マネージ コードの場合) または IKnowledgeSyncProvider::BeginSession (アンマネージ コードの場合) を呼び出した後で、Sync Framework は同期先プロバイダーの SpecifyFilter メソッド (マネージ コードの場合) または IRequestFilteredSync::SpecifyFilter (アンマネージ コードの場合) を呼び出してフィルターのネゴシエーションを開始します。
SpecifyFilter の処理中、同期先プロバイダーはフィルターを FilterRequestCallback デリゲート (マネージ コードの場合) または Sync Framework で指定された IFilterRequestCallback::RequestFilter メソッド (アンマネージ コードの場合) にフィルターを渡します。要求されたフィルターを同期先プロバイダーが追跡しない場合は、フィルター選択の種類として CurrentItemsOnly (マネージ コードの場合) または FT_CURRENT_ITEMS_ONLY (アンマネージ コードの場合) が指定されます。要求されたフィルターを同期先プロバイダーが追跡する場合は、フィルター選択の種類として CurrentItemsAndVersionsForMovedOutItems (マネージ コードの場合) または FT_CURRENT_ITEMS_AND_VERSIONS_FOR_MOVED_OUT_ITEMS (アンマネージ コードの場合) が指定されます。
FilterRequestCallback (マネージ コードの場合) または RequestFilter (アンマネージ コードの場合) の処理中に、Sync Framework は同期元プロバイダーの TryAddFilter メソッド (マネージ コードの場合) または ISupportFilteredSync::AddFilter メソッド (アンマネージ コードの場合) を呼び出します。要求されたフィルターが同期元プロバイダーでサポートされていない場合、同期先プロバイダーはサポートされているフィルターが見つかるまで、フィルターの要求を続けます。
同期先プロバイダーは、同期元プロバイダーに受け入れられるフィルターを見つけることができない場合、SyncInvalidOperationException をスローする (マネージ コードの場合) か SYNC_E_FILTER_NOT_SUPPORTED などのエラー コードを返す (アンマネージ コードの場合) ことによって同期を終了できます。
フィルターのネゴシエーションが正常に終了すると、同期元プロバイダーは、このフィルターを使用して、変更の列挙時に含める項目を決定します。
フィルターのネゴシエーションの詳細については、「フィルター ネゴシエーションの方法」を参照してください。
参照
概念
標準のカスタム プロバイダーの実装
同期アプリケーションの実装
列挙された項目をフィルターする方法
列挙された変更単位をフィルター選択する方法
フィルター ネゴシエーションの方法
フィルターを追跡し、フィルターされた変更を列挙する方法
レプリカをフィルターする方法