Управление метаданными для простых поставщиков
Простой поставщик требует хранения метаданных в службах хранилища метаданных, реализованных в объекте 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 имеет три свойства.
-
Пользовательские поля представляют собой поля в хранилище метаданных, идентифицируемые целыми числами. Если приложению требуется понятное имя для одного или нескольких полей, необходимо сопоставить это целое число с именем. Пользовательские поля можно определять в двух целях: для идентификации элементов и для предоставления информации о версиях этих элементов. Поля версий позволяют платформе Sync Framework определять, был ли изменен элемент или базовая единица. В данном примере поля версий содержат действительные данные из хранилища элементов, и для каждого поля в хранилище элементов имеется соответствующее поле. Такое соответствие «один к одному» необязательно, но эффективно. Более практичным решением было бы создание хэша из полей элементов и хранение его в одном пользовательском поле.
-
Правило идентификации определяет, какое пользовательское поле или группа полей используется для идентификации элемента. В данном случае используется поле
CUSTOM_FIELD_ID
(поле 0). ChangeUnitVersionDefinitions (в этом образце не используется)
Если используются базовые единицы, для них необходимо определить поля версий. При этом не требуется устанавливать сопоставление «один к одному» между базовыми единицами и информацией о версии или хранить актуальные данные. Базовые единицы могут охватывать сразу несколько полей. Например, приложение может указать, что поля
Zip
иPhone
составляют одну базовую единицу, а полеGuid
– другую. Для поляGuid
можно использовать актуальные данные, а для второй базовой единицы — хэш на основе полейZip
иPhone
или некоторый другой механизм определения версии.
Некоторые из методов, оперирующих данными хранилища элементов, такие как InsertItem, требуют на входе коллекцию объектов ItemField, представляющих каждое из полей. Объекты ItemFieldDictionary, используемые в качестве параметров таких методов, имеют значения индекса, совпадающие с индексами объектов CustomFieldDefinition.
См. также
Основные положения
Реализация простого пользовательского поставщика
Как создать управляемый простой поставщик