Compartir a través de


Filtrar datos de proveedores simples

En algunas situaciones, la réplica de destino solamente necesita un subconjunto de los datos que están disponibles en la réplica de origen. Por ejemplo, un vendedor podría necesitar información detallada solamente de los productos que vende habitualmente. Los proveedores simples permiten que las réplicas filtren los datos implementando una interfaz de filtro. El filtro de los datos permite hacer lo siguiente:

  • Reducir el volumen de datos enviados a través de la red.

  • Reducir la cantidad de espacio necesaria para el almacenamiento de una réplica. Esto es especialmente importante para los dispositivos.

  • Proporcionar particiones de datos personalizadas, basadas en los requisitos individuales de la réplica.

  • Evitar o reducir los conflictos porque particiones de datos distintas pueden enviarse a réplicas diferentes.

Tener en cuenta que los proveedores simples no pueden usar filtros personalizados; de lo contrario, pueden producirse resultados inesperados. Los filtros personalizados son filtros que usan la clase CustomFilterInfo (en código administrado) o la interfaz ICustomFilterInfo (en código no administrado).

Para filtrar los datos, utilice las interfaces siguientes:

Ejemplo de código administrado

En el ejemplo de código siguiente se utilizan las interfaces de negociación de filtros para determinar si debería utilizarse un filtro concreto durante una sesión de sincronización. Con la negociación de filtros, un proveedor de destino puede especificar que el proveedor de origen utilice uno o más filtros durante la enumeración de cambios; el proveedor de origen puede aceptar o rechazar un filtro. Si un proveedor de origen no admite ninguno de los filtros solicitados, el proveedor de destino puede decidir si recibir todos los datos y efectuar el filtrado él mismo. Sync Framework llama a los proveedores de forma apropiada para negociar el uso del filtro.

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 = ""

En el ejemplo de código siguiente primero se especifica una opción de filtro de None. Esto significa que los elementos deben filtrarse aun cuando ya se conozcan en el destino. En el ejemplo de código se implementa a continuación el método IsItemInFilterScope, que filtra los elementos en función de uno de los valores de campo de elemento. Una vez definido el filtro, en el ejemplo de código se implementa el método UseFilterThisSession. De este modo, la aplicación puede especificar si los filtros deben utilizarse en cada sesión.

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

Vea también

Conceptos

Implementar un proveedor simple personalizado
Crear un proveedor simple administrado