Compartir a través de


Filtrar elementos enumerados

En este tema se describe la forma de utilizar un lenguaje administrado para filtrar los elementos enumerados por un proveedor de sincronización de Sync Framework que sincroniza los datos de un almacén de datos personalizado.

En este tema se presupone que se dispone de un conocimiento básico de C# y conceptos de Microsoft .NET Framework.

Los ejemplos de este tema se centran en los siguientes miembros y clases de Sync Framework:

Descripción del filtrado de elementos

Un filtro de elementos restringe qué cambios de elementos son enviados por el proveedor de origen durante la enumeración de cambios, como por ejemplo enviar solamente los archivos .txt de una carpeta de archivos, omitiendo los archivos de otro tipo. Los elementos no se deben modificar de forma que un elemento existente pase a incluirse o excluirse del filtro. Los filtros de elementos son fáciles de usar, pero los metadatos utilizados para la sincronización crecen proporcionalmente al número de elementos que están en el ámbito de sincronización. Si el almacenamiento constituye un problema, los filtros personalizados son los más adecuados. Para obtener más información sobre los filtros personalizados, vea Filtrar los datos de sincronización.

El modo en que los elementos se filtran no está definido en Sync Framework; normalmente lo definen el desarrollador de software del proveedor o un tercero. El filtro lo puede establecer la aplicación de sincronización utilizando un mecanismo que sea adecuado entre la aplicación y el proveedor, o se puede negociar entre los dos proveedores. Para obtener más información acerca de la negociación de filtros, vea Filtrar los datos de sincronización.

El proveedor de destino recibe y aplica cambios del mismo modo que en el caso de un lote de cambios estándar. No se requiere realizar una acción especial para el filtrado.

Requisitos de la generación

Ejemplo

El código de ejemplo de este tema muestra cómo implementar un filtro de elementos simple y cómo utilizar Metadata Storage Service para crear un lote de cambios filtrado. La réplica de este ejemplo es un archivo de texto que almacena información de contacto en forma de lista de valores separados por comas. Los elementos para sincronizar son los contactos que contiene este archivo. El filtro se define de manera que solamente incluya los contactos cuyo campo de fecha de nacimiento sea menor que el valor especificado por la aplicación.

Establecer el filtro

El proveedor de origen implementa un método público que permite a la aplicación establecer un filtro que define el valor máximo para el campo de fecha de nacimiento. Cualquier contacto con un valor mayor que este valor en el campo de fecha de nacimiento no se incluirá en un lote de cambios.

public void SetMaximumBirthdateFilter(DateTime maxBirthdateFilter)
{
    // Store the fact that a filter is set, and the value of the filter.
    _isFiltered = true;
    _maxBirthdateFilter = maxBirthdateFilter;
}

La aplicación de sincronización crea el proveedor de origen como proveedor local y utiliza el método SetMaximumBirthdateFilter para especificar la fecha de nacimiento máxima que se ha de incluir al enumerar los cambios. La aplicación también crea el proveedor de destino y realiza la sincronización.

private void SynchronizeWithItemFiltering(ContactStore localStore, ContactStore remoteStore, SyncDirectionOrder syncDir)
{
    // Create the local provider and set the item filter.
    // The filter is ignored when the provider is the destination provider.
    SyncProvider localProvider = new ContactsProviderItemFiltering(localStore);
    // Only include contacts with a birthdate before January 1, 2000.
    ((ContactsProviderItemFiltering)localProvider).SetMaximumBirthdateFilter(
        new DateTime(2000, 1, 1));

    // Create the remote provider and do not set a filter.
    SyncProvider remoteProvider = new ContactsProviderItemFiltering(remoteStore);

    // Create the synchronization orchestrator and set the providers and synchronization direction.
    SyncOrchestrator orchestrator = new SyncOrchestrator();
    orchestrator.LocalProvider = localProvider;
    orchestrator.RemoteProvider = remoteProvider;
    orchestrator.Direction = syncDir;

    string msg;
    try
    {
        // Synchronize data between the two providers.
        SyncOperationStatistics stats = orchestrator.Synchronize();

        // Display statistics for the synchronization operation.
        msg = "Synchronization succeeded!\n\n" +
            stats.DownloadChangesApplied + " download changes applied\n" +
            stats.DownloadChangesFailed + " download changes failed\n" +
            stats.UploadChangesApplied + " upload changes applied\n" +
            stats.UploadChangesFailed + " upload changes failed";
    }
    catch (Exception ex)
    {
        msg = "Synchronization failed! Here's why: \n\n" + ex.Message;
    }
    MessageBox.Show(msg, "Synchronization Results");
}

Enumerar un lote de cambios filtrado

El proveedor de origen implementa GetChangeBatch para que, cuando se haya especificado un filtro, utilice Metadata Storage Service para crear un lote de cambios filtrado. Esto se realiza creando un objeto ItemListFilterInfo y pasándolo al método GetFilteredChangeBatch del objeto ReplicaMetadata.

public override ChangeBatch GetChangeBatch(uint batchSize, SyncKnowledge destinationKnowledge, out object changeDataRetriever)
{
    // Return this object as the IChangeDataRetriever object that is called to retrieve item data.
    changeDataRetriever = this;

    // Use the metadata storage service to get a batch of changes.
    ChangeBatch retrievedBatch;
    if (_isFiltered)
    {
        // If a filter is set, get a filtered change batch from the metadata storage service.
        // The BirthdateFilterCallback method indicates whether an item passes the filter.
        ItemListFilterInfo filterInfo = new ItemListFilterInfo(IdFormats);
        retrievedBatch = _ContactStore.ContactReplicaMetadata.GetFilteredChangeBatch(batchSize, destinationKnowledge,
            filterInfo, BirthdateFilterCallback);
    }
    else
    {
        retrievedBatch = _ContactStore.ContactReplicaMetadata.GetChangeBatch(batchSize, destinationKnowledge);
    }

    return retrievedBatch;
}

Para determinar si un elemento está incluido en el filtro, el método GetFilteredChangeBatch toma un delegado ItemFilterCallback que es implementado por el proveedor de origen. Metadata Storage Service llama a este delegado y utiliza el valor devuelto para incluir o excluir elementos del lote de cambios. En este ejemplo, un elemento se incluye en el lote de cambios cuando el valor del campo de fecha de nacimiento es menor que la fecha de nacimiento máxima especificada.

public bool BirthdateFilterCallback(ItemMetadata itemMeta)
{
    // An item passes the filter only if its birthdate field is less than the maximum birthdate
    // specified by the filter.
    return (_ContactStore.ContactList[itemMeta.GlobalId].Birthdate < _maxBirthdateFilter);
}

Pasos siguientes

A continuación, puede agregar la negociación de filtros al proveedor de modo que pueda comunicar con el proveedor de destino para establecer el filtro que se ha de usar en la enumeración de cambios. Para obtener más información sobre cómo se negocian los filtros, vea Negociar un filtro.

También puede utilizar un filtro personalizado en lugar de un filtro de elementos. Los filtros personalizados requieren más trabajo para su implementación, pero son mucho más eficaces para el seguimiento y la comunicación, por lo que su uso hace que el número de metadatos de sincronización siga siendo pequeño. Para obtener más información sobre los filtros personalizados, vea Filtrar los datos de sincronización.

Vea también

Conceptos

Programar tareas comunes de un proveedor personalizado estándar
Filtrar los datos de sincronización