Поделиться через


Как отфильтровать перечисляемые базовые единицы

В этом разделе описывается использование управляемого языка для фильтрации базовых единиц, перечисление которых выполняется службой синхронизации платформы Sync Framework, синхронизирующего данные из пользовательского хранилища данных.

Материал этого раздела предполагает, что читатель владеет основными понятиями языка C# и платформы Microsoft .NET Framework.

В примерах, приведенных в этом разделе, рассматриваются в основном следующие классы и члены платформы Sync Framework.

Основные сведения о фильтрации базовых единиц

Фильтры базовых единиц ограничивают данные синхронизации подмножеством базовых единиц, например синхронизируют только поля имени и телефонного номера контакта, не обрабатывая остальные базовые единицы. Фильтр базовых единиц полезен в случае, когда в реплике хранится лишь подмножество базовых единиц, определенных для элементов из области.

Платформа Sync Framework предоставляет объект ChangeUnitListFilterInfo для определения списка базовых единиц, которые необходимо включить в перечисление изменений. Фильтр можно настроить с помощью любого подходящего механизма путем приложения синхронизации между приложением и поставщиком либо между двумя поставщиками. Дополнительные сведения о согласовании фильтров см. в разделе Фильтрация данных синхронизации.

Если фильтр базовых единиц определен, платформа Sync Framework при вызове метода LoadChangeData поставщика источника запрашивает данные только для базовых единиц, содержащихся в фильтре.

Поставщик назначения получает и применяет изменения аналогично получению и применению изменений для стандартного пакета изменений за исключением того, что данные, отправленные в метод SaveChangeWithChangeUnits, содержат только базовые единицы, содержащиеся в фильтре.

Требования построения

Примеры

Код в примере в этом разделе используется для описания использования службы хранилища метаданных для создания пакета изменений, фильтрующего базовые единицы, включаемые в пакет изменений. Реплика в этом примере является текстовым файлом, в котором хранится контактная информация в виде списка значений с разделителями-запятыми. Синхронизируемыми элементами являются контакты, содержащиеся в этом файле. Фильтр определен для включения только полей адреса и телефонного номера контакта.

Настройка фильтра

Поставщик источника реализует открытый метод, позволяющий приложению настроить фильтр базовых единиц, определяющий для включения поля контактов при перечислении изменений.

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

Приложение синхронизации создает поставщика источника как локального поставщика и использует метод SetContactFieldsToInclude, чтобы указать для включения только поля с именем и телефонным номером контакта при перечислении изменений. Это приложение также создает поставщика назначения и выполняет синхронизацию.

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

Перечисление фильтрованного пакета изменений

Поставщик источника реализует метод GetChangeBatch, поэтому при указании фильтра он использует службу хранилища метаданных для создания фильтрованного пакета изменений. Это выполняется с помощью создания объекта ChangeUnitListFilterInfo, инициализация которого выполняется с помощью указанного для включения списка базовых единиц. Сведения о фильтре передаются методу GetFilteredChangeBatch объекта ReplicaMetadata. Службе хранилища метаданных не нужно выполнять ответный вызов поставщика для определения элементов, которые необходимо включить в фильтр, поэтому для параметра filterCallback указывается значение null.

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

Следующие шаги

Затем к поставщику необходимо добавить согласование фильтров для поддержки его взаимодействия с поставщиком назначения для определения фильтра, который будет использоваться для перечисления изменений. Дополнительные сведения о согласовании фильтров см. в разделе Как согласовать фильтр.

См. также

Основные положения

Программирование типовых задач стандартных пользовательских поставщиков
Фильтрация данных синхронизации