Condividi tramite


Procedura: filtrare gli elementi enumerati

In questo argomento viene illustrato come utilizzare un linguaggio gestito per filtrare gli elementi enumerati da un provider di sincronizzazione di Sync Framework per la sincronizzazione dei dati da un archivio dati personalizzato.

Questo argomento presuppone una conoscenza di base dei concetti relativi a C# e Microsoft .NET Framework.

Gli esempi riportati in questo argomento riguardano i membri e le classi di Sync Framework seguenti:

Informazioni sul filtro degli elementi

Un filtro degli elementi limita le modifiche dell'elemento inviate dal provider di servizio durante l'enumerazione delle modifiche, ad esempio per inviare solo file con estensione txt in una cartella di file, ignorando file di altri tipi. Gli elementi non devono essere modificati in modo da causare lo spostamento di un elemento esistente all'interno o all'esterno del filtro. L'utilizzo dei filtri degli elementi è semplice ma le dimensioni dei metadati utilizzati per la sincronizzazione aumentano proporzionalmente al numero di elementi che si trovano nell'ambito di sincronizzazione. Se l'archiviazione rappresenta un problema, i filtri personalizzati sono la soluzione appropriata. Per ulteriori informazioni sui filtri personalizzati, vedere Filtro dei dati di sincronizzazione.

Il modo in cui vengono filtrati gli elementi è definito all'esterno di Sync Framework, in genere dallo sviluppatore del provider o da terze parti. Il filtro può essere impostato dall'applicazione di sincronizzazione tramite qualsiasi meccanismo si ritenga appropriato tra l'applicazione e il provider o può essere negoziato tra i due provider. Per ulteriori informazioni sulla negoziazione dei filtri, vedere Filtro dei dati di sincronizzazione.

Il provider di destinazione riceve e applica le modifiche con la stessa modalità utilizzata per un batch di modifiche standard. Non richiede alcuna azione speciale per quanto riguarda il filtro.

Requisiti di compilazione

Esempio

Nel codice di esempio di questo argomento viene illustrato come implementare un filtro degli elementi semplice e come utilizzare il servizio di archiviazione dei metadati per produrre un batch di modifiche filtrato. La replica illustrata in questo esempio è un file di testo in cui sono archiviate informazioni di contatto come un elenco di valori delimitati da virgole. Gli elementi da sincronizzare sono i contatti contenuti in questo file. Il filtro è definito per includere solo i contatti che dispongono di un campo relativo alla data di nascita il cui valore è inferiore a quello specificato dall'applicazione.

Impostazione del filtro

Il provider di origine implementa un metodo pubblico che consente all'applicazione di impostare un filtro che definisce il valore massimo per il campo relativo alla data di nascita. Qualsiasi contatto con un valore maggiore di quello indicato nel campo della data di nascita non verrà incluso in un batch di modifiche.

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

L'applicazione di sincronizzazione crea il provider di origine come provider locale e utilizza il metodo SetMaximumBirthdateFilter per specificare la data di nascita massima da includere durante l'enumerazione delle modifiche. L'applicazione crea inoltre il provider di destinazione ed esegue la sincronizzazione.

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");
}

Enumerazione di un batch di modifiche filtrato

Il provider di origine implementa GetChangeBatch in modo che, quando un filtro viene specificato, viene utilizzato il servizio di archiviazione dei metadati per produrre un batch di modifiche filtrato. Questa operazione viene eseguita creando un oggetto ItemListFilterInfo e passandolo al metodo GetFilteredChangeBatch dell'oggetto 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;
}

Per determinare se un elemento è incluso nel filtro, il metodo GetFilteredChangeBatch accetta un delegato ItemFilterCallback che viene implementato dal provider di origine. Il servizio di archiviazione dei metadati chiama questa delegato e utilizza il valore restituito per includere o escludere elementi dal batch di modifiche. In questo esempio, un elemento viene incluso nel batch di modifiche quando il valore del campo della data di nascita è inferiore alla data di nascita massima.

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);
}

Passaggi successivi

A questo punto, si potrebbe volere aggiungere la negoziazione del filtro al provider in uso in modo che possa comunicare con il provider di destinazione per stabilire quale filtro utilizzare per l'enumerazione delle modifiche. Per ulteriori informazioni su come negoziare i filtri, vedere Procedura: negoziare un filtro.

Si potrebbe inoltre voler utilizzare un filtro personalizzato al posto di un filtro degli elementi. I filtri personalizzati richiedono un ulteriore lavoro di implementazione ma sono più efficienti per le operazioni di rilevamento e comunicazione, pertanto il loro utilizzo consente di mantenere contenute le dimensioni dei metadati di sincronizzazione. Per ulteriori informazioni sui filtri personalizzati, vedere Filtro dei dati di sincronizzazione.

Vedere anche

Concetti

Programmazione di attività comuni del provider standard personalizzato
Filtro dei dati di sincronizzazione