Управление метаданными для простых поставщиков

Простой поставщик требует хранения метаданных в службах хранилища метаданных, реализованных в объекте SqlMetadataStore (для управляемого кода) и ISqlSyncMetadataStore (для неуправляемого кода).

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

  • Идентификатор реплики. Идентифицирует реплику, использующую конкретное хранилище.

  • Идентификаторы и версии элементов. Идентифицируют все элементы, перечисленные в хранилище элементов, и текущую версию этого элемента.

  • Идентификаторы и версии базовых единиц. Они по желанию разработчика идентифицируют части элемента, изменения которых необходимо отслеживать, и текущую версию каждой части. Например, контактное лицо в базе данных контактов может быть элементом, а поле «номер телефона» — одной из базовых единиц.

Идентификация элементов в хранилище элементов и хранилище метаданных

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

Задание формата идентификаторов хранилища метаданных

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

public MyFullEnumerationSimpleSyncProvider(string name, MySimpleDataStore store)
{
    _name = name;
    _store = store;

    // Create a file to store metadata for all items and a file to store 
    // the replica ID.
    _replicaMetadataFile = Environment.CurrentDirectory + "\\" + _name.ToString() + ".Metadata";
    _replicaIdFile = Environment.CurrentDirectory + "\\" + _name.ToString() + ".Replicaid";

    // Set ReplicaIdFormat to use a GUID as an ID, and ItemIdFormat to use a GUID plus
    // an 8-byte prefix.
    _idFormats = new SyncIdFormatGroup();
    _idFormats.ItemIdFormat.IsVariableLength = false;
    _idFormats.ItemIdFormat.Length = 24;
    _idFormats.ReplicaIdFormat.IsVariableLength = false;
    _idFormats.ReplicaIdFormat.Length = 16;

    this.ItemConstraint += new EventHandler<SimpleSyncItemConstraintEventArgs>(OnItemConstraint);
    this.ItemConflicting += new EventHandler<SimpleSyncItemConflictingEventArgs>(OnItemConflicting);
}
public SyncId ReplicaId
{
    get 
    {
        if (_replicaId == null)
        {
            _replicaId = GetReplicaIdFromFile( _replicaIdFile);
        }

        return _replicaId; 
    }
}

public override SyncIdFormatGroup IdFormats
{
    get { return _idFormats; }
}
Public Sub New(ByVal name As String, ByVal store As MySimpleDataStore)
    _name = name
    _store = store

    ' Create a file to store metadata for all items and a file to store 
    ' the replica ID. 
    _replicaMetadataFile = (Environment.CurrentDirectory & "\") + _name.ToString() & ".Metadata"
    _replicaIdFile = (Environment.CurrentDirectory & "\") + _name.ToString() & ".Replicaid"

    ' Set ReplicaIdFormat to use a GUID as an ID, and ItemIdFormat to use a GUID plus 
    ' an 8-byte prefix. 
    _idFormats = New SyncIdFormatGroup()
    _idFormats.ItemIdFormat.IsVariableLength = False
    _idFormats.ItemIdFormat.Length = 24
    _idFormats.ReplicaIdFormat.IsVariableLength = False
    _idFormats.ReplicaIdFormat.Length = 16

    AddHandler Me.ItemConstraint, AddressOf HandleItemConstraint
    AddHandler Me.ItemConflicting, AddressOf HandleItemConflicting
End Sub
Public ReadOnly Property ReplicaId() As SyncId
    Get
        If _replicaId Is Nothing Then
            _replicaId = GetReplicaIdFromFile(_replicaIdFile)
        End If

        Return _replicaId
    End Get
End Property

Public Overrides ReadOnly Property IdFormats() As SyncIdFormatGroup
    Get
        Return _idFormats
    End Get
End Property

Задание полей элементов и схемы метаданных

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

public const uint CUSTOM_FIELD_ID = 1;
public const uint CUSTOM_FIELD_TIMESTAMP = 2;
public override ItemMetadataSchema MetadataSchema
{
    get
    {
        CustomFieldDefinition[] customFields = new CustomFieldDefinition[2];
        customFields[0] = new CustomFieldDefinition(CUSTOM_FIELD_ID, typeof(ulong));
        customFields[1] = new CustomFieldDefinition(CUSTOM_FIELD_TIMESTAMP, typeof(ulong));

        IdentityRule[] identityRule = new IdentityRule[1];
        identityRule[0] = new IdentityRule(new uint[] { CUSTOM_FIELD_ID });

        return new ItemMetadataSchema(customFields, identityRule);
    }
}
Public Const CUSTOM_FIELD_ID As UInteger = 1
Public Const CUSTOM_FIELD_TIMESTAMP As UInteger = 2
Public Overrides ReadOnly Property MetadataSchema() As ItemMetadataSchema
    Get
        Dim customFields As CustomFieldDefinition() = New CustomFieldDefinition(1) {}
        customFields(0) = New CustomFieldDefinition(CUSTOM_FIELD_ID, GetType(ULong))
        customFields(1) = New CustomFieldDefinition(CUSTOM_FIELD_TIMESTAMP, GetType(ULong))

        Dim identityRule As IdentityRule() = New IdentityRule(0) {}
        identityRule(0) = New IdentityRule(New UInteger() {CUSTOM_FIELD_ID})

        Return New ItemMetadataSchema(customFields, identityRule)
    End Get
End Property

Объект ItemMetadataSchema имеет три свойства.

  • CustomFields

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

  • IdentityRules

    Правило идентификации определяет, какое пользовательское поле или группа полей используется для идентификации элемента. В данном случае используется поле CUSTOM_FIELD_ID (поле 0).

  • ChangeUnitVersionDefinitions (в этом образце не используется)

    Если используются базовые единицы, для них необходимо определить поля версий. При этом не требуется устанавливать сопоставление «один к одному» между базовыми единицами и информацией о версии или хранить актуальные данные. Базовые единицы могут охватывать сразу несколько полей. Например, приложение может указать, что поля Zip и Phone составляют одну базовую единицу, а поле Guid – другую. Для поля Guid можно использовать актуальные данные, а для второй базовой единицы — хэш на основе полей Zip и Phone или некоторый другой механизм определения версии.

Некоторые из методов, оперирующих данными хранилища элементов, такие как InsertItem, требуют на входе коллекцию объектов ItemField, представляющих каждое из полей. Объекты ItemFieldDictionary, используемые в качестве параметров таких методов, имеют значения индекса, совпадающие с индексами объектов CustomFieldDefinition.

См. также

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

Реализация простого пользовательского поставщика
Как создать управляемый простой поставщик