Administrar metadatos para proveedores simples

Un proveedor simple requiere que almacene los metadatos en servicios de almacenamiento de metadatos, los cuales se implementan en SqlMetadataStore (para código administrado) y en ISqlSyncMetadataStore (para código no administrado).

El almacén de metadatos contiene los siguientes tipos de metadatos (con los que van a interactuar un proveedor o una aplicación):

  • Identificador de réplica. Identifica la réplica que utiliza un almacén determinado.

  • Identificadores de elemento y de versiones. Identifican cada elemento que se ha enumerado desde un almacén de elementos y la versión actual de ese elemento.

  • Identificadores de unidad de cambio y de versiones. Identifican de forma opcional las partes de un elemento al que se debe realizar un seguimiento y la versión actual de cada parte. Por ejemplo, un contacto en una base de datos de contactos podría ser un elemento y el campo de número de teléfono podría ser una de las unidades de cambio.

Identificar elementos en el almacén de elementos y en el almacén de metadatos

Para sincronizar un elemento, Sync Framework debe poder identificar el elemento en el almacén de elementos y asignar esa identidad a un identificador interno en el almacén de metadatos. También debe poder determinar si la versión del elemento ha cambiado desde la última sesión de sincronización. Si la versión ha cambiado y la réplica de destino aún no contiene esa versión de un elemento, se debería sincronizar el elemento. Si los cambios se sincronizan en el nivel de una unidad de cambio en lugar de en el de un elemento, Sync Framework debe poder identificar la unidad de cambio y su versión. Una unidad de cambio representa un cambio de subelemento, como el campo de número de teléfono en un elemento que representa un contacto. En este ejemplo no se utilizan unidades de cambio.

Especificar el formato de los identificadores del almacén de metadatos

En el ejemplo de código siguiente se define el constructor de MyFullEnumerationSimpleSyncProvider y la propiedad IdFormats. Esto permite al tiempo de ejecución de Sync Framework determinar qué formato utiliza el almacén de metadatos para los identificadores. Si no se utilizan identificadores flexibles, Sync Framework usa un formato fijo para identificar réplicas, elementos y unidades de cambio. Si se utilizan identificadores flexibles, los métodos ISimpleSyncProviderIdGenerator se usan para generar identificadores.

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

Especificar campos de elemento y el esquema de metadatos

Sync Framework asigna los datos de almacén de elementos, o los metadatos adicionales que pueda crear, a las versiones e identificadores del almacén de metadatos internos mediante un objeto ItemMetadataSchema expuesto por la propiedad MetadataSchema. En los ejemplos de código siguientes se proporciona la entrada para el objeto ItemMetadataSchema. Las constantes del código de ejemplo definen un valor entero para cada columna del almacén de elementos. Estos valores se usan cuando se crean las definiciones de campos personalizados y las reglas de identidad para el objeto 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

El objeto ItemMetadataSchema expone tres propiedades:

  • CustomFields

    Los campos personalizados son campos en el almacén de metadatos que están identificados por enteros. Si una aplicación requiere un nombre descriptivo para uno o más campos, debería asignar el entero a un nombre. Los campos personalizados se definen por dos razones: para identificar los elementos y para proporcionar información sobre la versión acerca de esos elementos. Los campos de versión hacen que Sync Framework determine si un elemento o unidad de cambio se han modificado. En este ejemplo, los campos de versión contienen los datos reales del almacén de elementos, así que hay un campo para cada campo en el almacén de elementos. No se requiere esta relación uno a uno, ni tampoco resulta eficaz. Una solución más práctica sería tomar un hash del campo de elemento y almacenarlo en un campo personalizado único.

  • IdentityRules

    La regla de identidad especifica los campos personalizados que se debería utilizar para identificar un elemento. En este caso, se utiliza el campo CUSTOM_FIELD_ID (campo 0).

  • ChangeUnitVersionDefinitions (no se utiliza en este ejemplo)

    Si se utilizan unidades de cambio, debe definir los campos de versión para éstas. No es necesario que haya asignaciones unívocas entre las unidades de cambio y la información sobre la versión o que los datos reales deban estar almacenados. Las unidades de cambio también pueden abarcar varios campos. Por ejemplo, esta aplicación podría especificar que Zip y Phone son una unidad de cambio y que Guid es otra. Para Guid, podría utilizar los datos reales y para la otra unidad de cambio un hash de los campos Zip y Phone, o algún otro mecanismo para determinar la versión.

Para algunos de los métodos que funcionan con los datos de almacén de elementos, como InsertItem, es necesario recopilar los objetos ItemField que representan a cada campo. Los objetos ItemFieldDictionary que son los parámetros para estos métodos tienen los mismos valores de índice que los especificados en los objetos CustomFieldDefinition.

Vea también

Conceptos

Implementar un proveedor simple personalizado
Crear un proveedor simple administrado