7

阅读数据合同版本控制后,我们得出结论,这并不是故事的全部。例如,如果您以前有 ValueA,而在新版本中它现在称为 ValueB 并且属于不同类型,您需要将 ValueA 转换为 ValueB,会发生什么情况?

我可以使用一些回调来帮助解决这个问题,但如果我们期望格式在很长一段时间内频繁更改,它看起来不是一个非常可维护的解决方案。

我们解决的解决方案是保留“按版本保存”字段,并在加载文件时根据需要调用特定于旧版本的转换例程。这些转换例程知道如何将旧数据的 XML 转换为新数据的 XML。

然而,事实证明,DataContractSerializes 要求元素的顺序完全符合它的预期。这意味着我们的转换过程必须知道将元素插入到正确的位置。如果考虑到继承,这比简单地添加具有已知名称的元素要困难得多。使用继承,您不能可靠地AddBeforeSelfAddAfterSelf 任何字段,这仅仅是因为没有一个字段始终位于该新字段旁边。

撇开 DataContractSerializer 如此严格的原因不谈,你能建议解决这个问题的方法吗?也许是一篇关于如何与非常旧的数据合约保持向后兼容的好文章,在您对格式进行第 100 次重大更改时不会变得笨拙。

本文中有一些额外的指导方针,但这一定是为了不同的目的而编写的。例如,我们不可能让旧数据成员永远闲置(第 9 点)。似乎大多数此类文章都是从通信协议的角度编写的,而不是将数据存储在文件中。

4

2 回答 2

4

一年后,我不得不说DataContractSerializer版本控制真的很糟糕。它太僵硬了。它真的适用于不太可能改变的合同,然后只能以特定的方式改变。您必须做额外的工作才能使用它来使其快速 - 例如 KnownTypeAttribute。如果您需要相对快速的序列化,我只会推荐它 - 可以说,这对于它的设计目的相当重要。

我从事的另一个项目使用了一个更灵活的序列化程序,例如,它不会跳过调用类构造函数(某些事情造成了很多不便),并且不需要项目按特定顺序排列。它优雅地处理新字段(它们保留在构造函数设置的任何位置)并在零程序员干预的情况下删除字段。

现在要是我能把它贴在这里就好了……不过它比 DataContractSerializer 慢了 5 到 10 倍。

于 2010-10-11T10:45:21.303 回答
3

我认为您对内置版本控制支持期望过高。它的真正目的是允许您添加新成员,同时保留所有现有功能和成员。

在对合同进行重大更改的情况下,您可能最好创建一个新版本的合同(例如,使用新的命名空间 - 一个常见的约定是使用后缀 yyyy/mm,例如http://mycompany.com /myservices/2009/10)。

然后,您需要能够支持尽可能多的旧合同,并且需要能够在每个支持的合同和您正在使用的任何当前内部表示之间进行转换。

于 2009-10-04T08:20:55.457 回答