Freigeben über


Vorgehensweise: Aktualisieren von Metadaten bei Änderung des Metadatenschemas durch den Anbieter

In diesem Thema wird beschrieben, wie Sie eine verwaltete Sprache für die Aktualisierung eines Metadaten-Speicherdienstspeichers verwenden können, wenn der Anbieter das Metadatenschema ändert.

Dieses Thema setzt grundlegende Kenntnisse über C#- und Microsoft .NET Framework-Konzepte voraus.

In den Beispielen dieses Themas liegt der Schwerpunkt auf den folgenden Sync Framework-Klassen und -Schnittstellen:

Grundlegendes zur Metadatenaktualisierung

Der Metadaten-Speicherdienst speichert Replikat- und Elementmetadaten in einer vereinfachten Datenbank. Ein Anbieter kann benutzerdefinierte Felder in der Datenbank definieren, die sich möglicherweise ändern, wenn ein Entwickler neue Versionen eines bestimmten Anbieters freigibt. Sync Framework bietet Support für die Aktualisierung des Metadatenspeichers aufgrund von Änderungen der Anbieterversion.

Eine Metadaten-Speicherupgrade ist nur erforderlich, wenn die benutzerdefinierten Felder von der Anbieteränderung verwendet werden. Änderungen am Format der Elementdaten wirken sich nicht auf das Format der Metadaten aus.

Wenn ein Anbieter Metadaten für ein Replikat speichert, legt er die mit den Replikatmetadaten kompatible Anbieterversion mithilfe von ProviderVersion fest. Wenn ein Anbieter später den Metadatenspeicher öffnet, kann er die Anbieterversion überprüfen, die den Replikatmetadaten zugewiesen wurde. Wenn sich die Version des Anbieters, der den Metadatenspeicher öffnet, von der Anbieterversion unterscheidet, die in den Metadaten gespeichert wurde, kann der Anbieter das Metadatenschema für das Replikat aktualisieren.

Ein Metadatenspeicher wird mit folgenden Schritten aktualisiert.

  1. Die Replikatmetadaten werden mithilfe eines SqlSyncMetadataStoreSerializer-Objekts serialisiert.

  2. Die Replikatmetadaten werden aus dem Metadatenspeicher entfernt.

  3. Replikatmetadaten im neuen Format werden im Metadatenspeicher erstellt.

  4. Die zuvor serialisierten Replikatmetadaten werden mithilfe des SqlSyncMetadataStoreSerializer-Objekts in das neue Format importiert.

Sync Framework stellt einen Rückrufmechanismus bereit (IProviderUpgradeCallback), um dem Anbieter die Steuerung des Aktualisierungsprozesses einschließlich aller erforderlichen Änderungen an den Metadaten zu ermöglichen.

Weitere Informationen finden Sie unter Aktualisieren der Metadatenspeicherversion.

Erstellungsanforderungen

Beispiel

Der Beispielcode in diesem Thema zeigt das Aktualisieren eines Metadatenspeichers, der während der Aktualisierung ein benutzerdefiniertes Feld hinzufügt. Der Wert des neuen Felds für die einzelnen Elemente im Metadatenspeicher wird mithilfe einer Klasse festgelegt, die IProviderUpgradeCallback implementiert.

Aktualisieren des Metadatenspeichers

In diesem Beispiel wird der Metadatenspeicher aktualisiert, wenn die aktuelle Anbieterversion der Replikatmetadaten niedriger als der angegebene Wert ist. Während der Aktualisierung wird dem Metadatenschema für das Replikat ein zusätzliches, benutzerdefiniertes Feld hinzugefügt und als Indexfeld angegeben.

Beachten Sie, dass das SqlMetadataStore-Objekt verworfen und neu geöffnet werden muss, damit alle Verweise auf das ReplicaMetadata-Objekt freigegeben werden. Wenn dies nicht geschieht, wird beim Aufrufen von RemoveReplicaMetadata ReplicaMetadataInUseException ausgelöst.

public static void UpgradeMetadataStore(SqlMetadataStore store, string storePath,
    SortedList<SyncId, Contact> contactList)
{
    // Get the provider version and replica ID from the metadata store.
    uint providerVersion = store.GetSingleReplicaMetadata().ProviderVersion;
    SyncId replicaId = store.GetSingleReplicaMetadata().ReplicaId;

    // Check the provider version of the metadata store and upgrade if necessary.
    if (providerVersion < (uint)ContactsProviderVersion.ContactsProvider_v2)
    {
        // Dispose the store to release all references to the replica metadata
        // or the call to RemoveReplicaMetadata will throw ReplicaMetadataInUseException.
        store.Dispose();
        store = null;

        // Reopen the store.
        store = SqlMetadataStore.OpenStore(storePath);

        // Start a transaction.
        store.BeginTransaction();

        // Serialize the metadata store in canonical format.
        string serializedName = "SerializedStoreForUpgrade.dat";
        SyncMetadataStoreSerializer mdsSerializer = store.GetMetadataStoreSerializer();
        mdsSerializer.SerializeReplicaMetadata(ContactStore.ContactIdFormatGroup, replicaId,
            serializedName, CompatibilityLevel.SyncFrameworkVersion1);
        
        // Remove the replica metadata from the store.
        store.RemoveReplicaMetadata(ContactStore.ContactIdFormatGroup, replicaId);

        // Initialize replica metadata, adding a new index column for Address.

        // Create custom fields for First Name, Last Name, Phone Number. These will be used
        // as unique index fields for identifying items between the metadata store and the item store.
        // Also include a custom field for Address, which will be used as an index.
        FieldSchema[] CustomFields = 
        {
            new FieldSchema(FirstNameField, typeof(string), 100),
            new FieldSchema(LastNameField, typeof(string), 100),
            new FieldSchema(PhoneNumberField, typeof(string), 20),
            new FieldSchema(AddressField, typeof(string), 100)
        };

        // Specify the index fields.
        string[] IndexFields = { FirstNameField, LastNameField, PhoneNumberField };
        IndexSchema[] Indexes = 
        {
            new IndexSchema(IndexFields, true),
            new IndexSchema(AddressField, false)
        };

        // Create the metadata for the replica in the metadata store.
        ReplicaMetadata newRepMeta = store.InitializeReplicaMetadata(
            ContactIdFormatGroup, replicaId, CustomFields, Indexes);

        // Import the serialized metadata.
        ContactsProviderUpgrader upgrader = new ContactsProviderUpgrader(contactList);
        mdsSerializer.DeserializeReplicaMetadata(serializedName, (uint)ContactsProviderVersion.ContactsProvider_v2,
            upgrader);

        // Set the new provider version.
        newRepMeta.ProviderVersion = (uint)ContactsProviderVersion.ContactsProvider_v2;

        newRepMeta.SaveReplicaMetadata();

        // Commit the transaction.
        store.CommitTransaction();
    }
}

Antworten auf Aktualisierungsrückrufe

In diesem Beispiel wird eine Klasse definiert, die die IProviderUpgradeCallback-Schnittstelle implementiert. Im vorigen Beispiel wurde eine Instanz dieser Klasse für die DeserializeReplicaMetadata-Methode angegeben. Sync Framework ruft die Methoden in dieser Schnittstelle auf, um dem Anbieter die Steuerung der Aktualisierung und alle erforderlichen Änderungen an den Metadaten zu ermöglichen. In der OnProviderUpgradeRequired-Methode in diesem Beispiel wird die Aktualisierung abgebrochen, wenn die derzeit in den Replikatmetadaten gespeicherte Anbieterversion nicht den erwarteten Wert aufweist. In der OnItemMetadataDeserialized-Methode in diesem Beispiel wird der Wert des neuen address-Felds in den Metadaten für die einzelnen Elemente festgelegt.

class ContactsProviderUpgrader : IProviderUpgradeCallback
{
    // The contact list is the item store. Save it so new metadata fields can be updated
    // during the upgrade.
    public ContactsProviderUpgrader(SortedList<SyncId, Contact> contactList) 
    {
        _contactList = contactList;
    }

    private SortedList<SyncId, Contact> _contactList;

    #region IProviderUpgradeCallback Members

    public void OnCustomReplicaMetadataDeserialized(byte[] customReplicaMetadata)
    {
        // This replica doesn't store custom replica metadata, so there's nothing to do!
    }

    public void OnItemMetadataDeserialized(ItemMetadata itemMetadata, Dictionary<string, SyncFieldValue> extraFields)
    {
        // The address field is new in the upgrade, so set it now from the contact list.
        Contact contact = _contactList[itemMetadata.GlobalId];
        itemMetadata.SetCustomField(ContactStore.AddressField, contact.Address);
    }

    public void OnProviderUpgradeRequired(uint dwCurrentProviderVersionInFile)
    {
        // This upgrader can only upgrade from provider version 1.
        if ((uint)ContactsProviderVersion.ContactsProvider_v1 != dwCurrentProviderVersionInFile)
        {
            throw new MetadataStoreProviderVersionMismatchException("Can't upgrade the metadata store from the specified version.");
        }
    }

Nächste Schritte

Als Nächstes sollten Sie sich mit dem Aktualisieren des Metadatenspeichers bei Änderung der Version von Sync Framework befassen. Weitere Informationen finden Sie unter Aktualisieren der Metadatenspeicherversion.

Sie können auch mehr darüber erfahren, wie das kanonische Format des Metadatenspeichers zur Aktivierung der Interoperabilität von Komponenten verschiedener Versionen verwendet werden kann, ohne dass eine Aktualisierung des Metadatenspeichers erforderlich ist. Weitere Informationen finden Sie unter Zugreifen auf Metadaten von Komponenten anderer Versionen.

Siehe auch

Konzepte

Programmieren allgemeiner benutzerdefinierter Standardanbietertasks
Aktualisieren der Metadatenspeicherversion