Share via


簡易プロバイダーのデータのフィルター選択

同期先レプリカに同期元レプリカのすべてのデータが必要とは限りません。データのサブセットだけでよい場合もあります。たとえば、販売担当者にとっては、普段自分が取り扱っている商品についてのみ詳しい情報が入手できれば十分です。簡易プロバイダーにフィルター選択インターフェイスを実装すると、レプリカのデータをフィルター選択できるようになります。データのフィルター選択により、次のことが可能になります。

  • ネットワーク経由で送信されるデータ量を削減できます。

  • レプリカで必要となる記憶領域を削減できます。これは、デバイスにとって特に重要な利点です。

  • 各レプリカの要件に基づいてカスタム データ パーティションを提供できます。

  • 異なるデータ パーティションをそれぞれ異なるレプリカに送信できるため、競合を回避または軽減できます。

簡易プロバイダーではカスタム フィルターを使用できないことに注意してください。使用すると、予期しない結果が生じる可能性があります。カスタム フィルターとは、CustomFilterInfo クラス (マネージ コードの場合) または ICustomFilterInfo インターフェイス (アンマネージ コードの場合) を使用するフィルターです。

データをフィルター選択するには、次のインターフェイスを使用します。

マネージ コードの例

次のコード例では、フィルターのネゴシエーション インターフェイスを使用して、同期セッション中に使用する特定のフィルターを決定します。フィルターのネゴシエーションを行うことで、同期先プロバイダーは、同期元プロバイダーに対し、1 つ以上のフィルターを使用して変更を列挙するように指定できます。同期元プロバイダーは、フィルターを受け入れることも、拒否することもできます。要求されたフィルターがいずれも同期元プロバイダーでサポートされていない場合、同期先プロバイダーでは、すべてのデータを受信し、自身でフィルター処理を行うことを選択できます。Sync Framework は、フィルターの使用をネゴシエートするプロバイダーを適切に呼び出します。

public bool RequestFilter
{
    set
    {
        _requestFilter = value; 
    }
}
private bool _requestFilter = false;

void IRequestFilteredSync.SpecifyFilter(FilterRequestCallback filterRequest)
{
    // Request a filter only if this provider represents a filtered replica.
    if (_requestFilter)
    {
        if (!filterRequest("TheFilter", FilteringType.CurrentItemsOnly))
        {
            throw new SyncInvalidOperationException("Could not agree on filter.");
        }
    }
}

bool ISupportFilteredSync.TryAddFilter(object filter, FilteringType filteringType)
{
    if (!((string)filter).Equals("TheFilter"))
    {
        throw new Exception("Filter is incorrect");
    }

    // Remember the filter.
    _filter = (string)filter;

    return true;
}
private string _filter = "";
Public WriteOnly Property RequestFilter() As Boolean
    Set(ByVal value As Boolean)
        _requestFilter = value
    End Set
End Property

Private _requestFilter As Boolean = False

Private Sub SpecifyFilter(ByVal filterRequest As FilterRequestCallback) Implements IRequestFilteredSync.SpecifyFilter
    ' Request a filter only if this provider represents a filtered replica.
    If _requestFilter Then
        If Not filterRequest("TheFilter", FilteringType.CurrentItemsOnly) Then
            Throw New SyncInvalidOperationException("Could not agree on filter.")
        End If
    End If
End Sub

Private Function TryAddFilter(ByVal filter As Object, ByVal filteringType As FilteringType) As Boolean Implements ISupportFilteredSync.TryAddFilter
    If Not DirectCast(filter, String).Equals("TheFilter") Then
        Throw New Exception("Filter is incorrect")
    End If

    ' Remember the filter.
    _filter = DirectCast(filter, String)

    Return True
End Function

Private _filter As String = ""

次のコード例では、まず、フィルター オプションとして None を指定します。これは、同期先が把握している項目も除外されることを意味します。コード例には、さらに、IsItemInFilterScope メソッドが実装されています。このメソッドで、項目フィールドのいずれかの値に基づいて項目を除外します。フィルター定義の後は、UseFilterThisSession メソッドが実装されています。これで、アプリケーションから、フィルター選択を使用するかどうかをセッション単位で指定できるようになります。

SimpleSyncProviderFilterOptions IFilteredSimpleSyncProvider.FilterOptions
{
    get
    {
        return SimpleSyncProviderFilterOptions.None;
    }
}

bool IFilteredSimpleSyncProvider.IsItemInFilterScope(ItemFieldDictionary KeyAndVersion)
{
    ulong itemId = (ulong)KeyAndVersion[1].Value;
    ItemData itemData = _store.Get(itemId);
    if (itemData["data"] == "3333")
    {
        return false;
    }

    return true;
}

bool IFilteredSimpleSyncProvider.UseFilterThisSession
{
    get
    {
        // Indicate whether a filter has been requested and agreed upon for this session.
        return ("" != _filter);
    }
}
Private ReadOnly Property FilterOptions() As SimpleSyncProviderFilterOptions Implements IFilteredSimpleSyncProvider.FilterOptions
    Get
        Return SimpleSyncProviderFilterOptions.None
    End Get
End Property

Private Function IsItemInFilterScope(ByVal KeyAndVersion As ItemFieldDictionary) As Boolean Implements IFilteredSimpleSyncProvider.IsItemInFilterScope
    Dim itemId As ULong = KeyAndVersion(1).Value
    Dim data As ItemData = _store.Get(itemId)
    If data("data") Is "3333" Then
        Return False
    End If

    Return True
End Function

Private ReadOnly Property UseFilterThisSession() As Boolean Implements IFilteredSimpleSyncProvider.UseFilterThisSession
    Get
        ' Indicate whether a filter has been requested and agreed upon for this session.
        Return "" Is _filter
    End Get
End Property

参照

概念

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