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


Как отфильтровать перечисляемые элементы

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

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

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

Основные сведения о фильтрации элементов

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

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

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

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

Примеры

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

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

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

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

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

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

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

Поставщик источника реализует метод GetChangeBatch, поэтому при указании фильтра он использует службу хранилища метаданных для создания фильтрованного пакета изменений. Это выполняется путем создания объекта ItemListFilterInfo и передачи его методу GetFilteredChangeBatch объекта 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;
}

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

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

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

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

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

См. также

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

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