升级元数据存储区版本
元数据存储服务在轻量级数据库中存储副本和项元数据。以特定表架构和二进制格式存储元数据,随着 Sync Framework 新版本的发布,该格式可能发生变更。此外,随着开发人员发布特定提供程序的新版本,数据库中的自定义提供程序字段也可能发生变更。对于由于 Sync Framework 版本变更和提供程序版本变更造成的变更,Sync Framework 提供元数据存储区的升级支持。
Sync Framework 还支持访问不同版本的组件中的元数据存储区,而不需要升级元数据存储区本身。有关更多信息,请参见访问来自不同版本的组件的元数据。
由于 Sync Framework 版本变更造成的升级
在 Sync Framework 2.0 和 Sync Framework 1.0 中,元数据存储区架构和文件格式是不同的。元数据存储区文件可以用 1.0 格式保存,但是为了提高效率,可以将该文件升级到 2.0 格式。
备注
元数据存储区文件的升级不能撤消。2.0 格式的文件无法降回到 1.0 格式。
通过 Sync Framework 2.0 打开 1.0 格式的元数据存储区文件时,该文件将自动升级到 2.0 格式,除非提供程序进行注册以接收升级通知并指示元数据存储服务不应升级文件格式。要控制是否升级,请执行以下步骤:
在打开元数据存储区文件前,注册接收 MetadataStoreUpgradeStart 事件(对于托管代码)或注册 IMetadataStoreUpgradeCallback 对象(对于非托管代码)。要注册 IMetadataStoreUpgradeCallback,请调用 ISyncMetadataStore2::SetMetadataStoreUpgradeNotificationCallback。
使用 OpenStore(对于托管代码)或 ISqlSyncMetadataStore::OpenStore(对于非托管代码)打开元数据存储区文件。
Sync Framework 检测到需要升级,并调用 MetadataStoreUpgradeStart 事件处理程序(对于托管代码)或 IMetadataStoreUpgradeCallback::OnMetadataStoreFileUpgradeStart 方法(对于非托管代码)。
提供程序使用 UpgradeStartEventArgs 对象的 SkipUpgrade 属性(对于托管代码)或 IMetadataStoreUpgradeCallback::OnMetadataStoreFileUpgradeStart 方法的 pfSkipUpgrade 参数(对于非托管代码)指示是否应升级元数据存储区文件。
由于提供程序版本变更造成的升级
提供程序使用 ProviderVersion(对于托管代码)或 IReplicaMetadata2::SetProviderVersion(对于非托管代码)设置与副本元数据兼容的提供程序版本。提供程序打开元数据存储区时,它可以使用 ProviderVersion(对于托管代码)或 IReplicaMetadata2::GetProviderVersion(对于非托管代码)检查与副本元数据关联的提供程序版本。打开元数据存储区的提供程序版本与元数据中存储的提供程序版本不同时,提供程序可以升级副本的元数据架构。要升级元数据架构,请执行以下步骤:
通过调用 BeginTransaction(对于托管代码)或 ISyncMetadataStore::BeginTransaction(对于非托管代码)来启动事务。
使用 SyncMetadataStoreSerializer(对于托管代码)或 ISyncMetadataStoreSerializer::SerializeReplicaMetadata(对于非托管代码)将副本元数据序列化为规范格式。
使用 RemoveReplicaMetadata(对于托管代码)或 ISyncMetadataStore2::RemoveReplicaMetadata(对于非托管代码)从元数据存储区中删除副本元数据。
使用 InitializeReplicaMetadata(对于托管代码)或 ISyncMetadataStore::InitializeReplicaMetadata(对于非托管代码)将元数据存储区中副本的新元数据初始化。在此调用中,指定已升级的元数据架构中的自定义列和索引。
使用 DeserializeReplicaMetadata(对于托管代码)或 ISyncMetadataStoreSerializer::DeserializeReplicaMetadata(对于非托管代码)导入已在步骤 1 中序列化的元数据。在此调用中指定升级的提供程序版本,并提供 IProviderUpgradeCallback(对于托管代码)或 IProviderMetadataUpgradeCallback(对于非托管代码)对象,该对象将接收在升级期间发生的事件的通知。
在升级期间,调用 OnCustomReplicaMetadataDeserialized(对于托管代码)或 IProviderMetadataUpgradeCallback::OnReplicaCustomFieldDeserialized(对于非托管代码),以允许提供程序对副本的自定义元数据字段进行任何变更。
在升级期间,对于反序列化的每个项调用一次 OnItemMetadataDeserialized(对于托管代码)或 IProviderMetadataUpgradeCallback::OnItemMetadataDeserialized(对于非托管代码),以允许提供程序对项的元数据进行任何变更。
使用 ProviderVersion(对于托管代码)或 IReplicaMetadata2::SetProviderVersion(对于非托管代码)在元数据中设置副本的已升级提供程序版本。
通过调用 CommitTransaction(对于托管代码)或 ISyncMetadataStore::CommitTransaction(对于非托管代码)来提交事务。
元数据兼容性注意事项
发布提供程序的新版本时,应考虑以下与元数据兼容性有关的注意事项:
副本 ID、项 ID 等的格式(对于托管代码在 SyncIdFormatGroup 中指定,对于非托管代码在 ID_PARAMETERS 结构 中指定)在特定同步社区内提供程序的所有实例和版本上必须相同。这是一般规则,为了完整性起见在此处重新提及。
不能以不兼容的方式变更副本的自定义字段。此字段是 Sync Framework 不进行干预的序列化和反序列化的 BLOB。不要因为变更字段结构而使早期提供程序版本无法读取或写入该字段。
在两个提供程序版本之间可以变更提供程序的自定义列和索引架构。这些架构可以选择在 InitializeReplicaMetadata 方法(对于托管代码)或 ISyncMetadataStore::InitializeReplicaMetadata 方法(对于非托管代码)中指定。但是,应当了解以下事项:
提供程序不能对元数据架构进行不兼容的变更。例如,您不能删除这样的自定义字段:以前版本的提供程序在每次进行项更新时需要更新该字段。
提供程序的新版本只有在更新这些列是可选的情况下才能添加自定义列。以前版本的提供程序不会知道这些列的存在。
将自定义列的名称和值序列化,但是这些列的数据类型、索引和其他架构信息不会序列化。这意味着在从规范文件导入元数据前,自定义列和索引在元数据存储区中必须存在。
不能在较新版本的提供程序中变更列数据类型。这可能导致早期版本的提供程序出现反序列化错误。