Condividi tramite


Procedura: filtrare unità di modifica enumerate

In questo argomento viene illustrato come utilizzare un linguaggio gestito per filtrare le unità di modifica enumerate 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 delle unità di modifica

I filtri delle unità di modifica limitano i dati di sincronizzazione a un subset di unità di modifica, ad esempio per sincronizzare solo i campi del nome e del numero di telefono di un contatto, ignorando le unità di modifica rimanenti. Il filtro delle unità di modifica è utile quando una replica archivia solo un subset delle unità di modifica definite per gli elementi nell'ambito.

Sync Framework fornisce l'oggetto ChangeUnitListFilterInfo per definire l'elenco di unità di modifica da includere in un'enumerazione delle modifiche. 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.

Quando un filtro delle unità di modifica viene definito, Sync Framework richiede i dati solo per le unità di modifica presenti nel filtro quando chiama LoadChangeData del provider di origine.

Il provider di destinazione riceve e applica le modifiche con la stessa modalità utilizzata per un batch di modifiche standard, con la differenza che i dati inviati a SaveChangeWithChangeUnits contengono solo le unità di modifica presenti nel filtro.

Requisiti di compilazione

Esempio

Nel codice di esempio di questo argomento viene illustrato come utilizzare il servizio di archiviazione dei metadati per produrre un batch di modifiche che filtra le unità di modifica incluse in tale batch. 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 viene definito per includere solo i campi del nome e del numero di telefono del contatto.

Impostazione del filtro

Il provider di origine implementa un metodo pubblico che consente all'applicazione di impostare un filtro delle unità di modifica che definisce i campi di contatto da includere durante l'enumerazione delle modifiche.

public void SetContactFieldsToInclude(Contact.ChangeUnitFields[] includedFields)
{
    // Translate the array of fields to a list of IDs.
    _includedChangeUnits = new List<SyncId>(includedFields.Length);
    for (int iField = 0; iField < includedFields.Length; iField++)
    {
        _includedChangeUnits.Add(new SyncId((byte)includedFields[iField]));
    }

    _isFiltered = true;
}

L'applicazione di sincronizzazione crea il provider di origine come provider locale e utilizza il metodo SetContactFieldsToInclude per specificare che devono essere inclusi solo i campi del nome e del numero di telefono durante l'enumerazione delle modifiche. L'applicazione crea inoltre il provider di destinazione ed esegue la sincronizzazione.

private void SynchronizeWithChangeUnitFiltering(ContactStore localStore, ContactStore remoteStore, SyncDirectionOrder syncDir)
{
    // Create the local provider and set the change unit filter.
    // The filter is ignored when the provider is the destination provider.
    SyncProvider localProvider = new ContactsProviderChangeUnitFiltering(localStore);
    // Only include name and phone number fields.
    Contact.ChangeUnitFields[] includedFields = new Contact.ChangeUnitFields[2];
    includedFields[0] = Contact.ChangeUnitFields.NameCU;
    includedFields[1] = Contact.ChangeUnitFields.PhoneCU;
    ((ContactsProviderChangeUnitFiltering)localProvider).SetContactFieldsToInclude(includedFields);
    
    // Create the remote provider and do not set a filter.
    SyncProvider remoteProvider = new ContactsProviderChangeUnitFiltering(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 ChangeUnitListFilterInfo, inizializzandolo con l'elenco specificato di unità di modifica da includere. Le informazioni sul filtro vengono passate al metodo GetFilteredChangeBatch dell'oggetto ReplicaMetadata. Il servizio di archiviazione dei metadati non deve richiamare il provider per stabilire quali elementi includere nel filtro, pertanto viene specificato null per il parametro filterCallback.

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;

    ChangeBatch retrievedBatch;
    if (_isFiltered)
    {
        // Use the metadata storage service to get a filtered batch of changes.
        ChangeUnitListFilterInfo filterInfo = new ChangeUnitListFilterInfo(IdFormats, _includedChangeUnits, true);
        retrievedBatch = _ContactStore.ContactReplicaMetadata.GetFilteredChangeBatch(batchSize, destinationKnowledge,
            filterInfo, null);
    }
    else
    {
        // Use the metadata storage service to get a batch of changes.
        retrievedBatch = _ContactStore.ContactReplicaMetadata.GetChangeBatch(batchSize, destinationKnowledge);
    }
    
    return retrievedBatch;
}

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.

Vedere anche

Concetti

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