2009-10-03 85 views
6

阅读Data Contract Versioning后,我们得出结论:这并不是真正的全部内容。例如,如果您曾经拥有ValueA,会发生什么情况,并且在新版本中它现在称为ValueB并且是不同类型的,您需要将ValueA转换为ValueB?使用DataContractSerializer进行版本控制的简单数据文件

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

我们为入驻的解决办法是保持一个“的版本保存的”现场,并在加载文件调用特定旧版本的转换程序的要求。这些转换例程知道如何将旧数据的XML转换为新数据的XML。

但是,事实证明,DataContractSerializes requires the order of the elements to be exactly what it expects。这意味着我们的转换过程必须知道将元素插入到正好是的正确位置。如果考虑继承,这比简单地添加一个已知名称的元素要困难得多。有了继承,你不能可靠地或AddAfterSelf任何场,仅仅是因为没有一个单一的领域,始终是旁边这个新领域。

撇开DataContractSerializer做得如此严格的原因,你能否提出解决方法?也许是一篇关于如何保持与旧数据合同向后兼容的伟大文章,在您对格式进行第100次重大更改时不会变得笨拙。

有在this article一些额外的指导方针,但必须用于不同的目的已经被写入。例如,我们不可能让旧数据成员永远悬挂(第9点)。看来,大多数这样的文章是从通信协议的角度来编写的,而不是将数据存储在文件中。

回答

2

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

在重大更改,以合同的情况下,你可能会得到更好的创建合同的新版本(例如使用新的命名空间 - 一个共同的约定使用后缀为yyyy/mm,例如http://mycompany.com/myservices/2009/10)。

然后,您需要能够支持尽可能多的老合同,只要适合,并且需要能够支持每一个合同,无论当前内部表示你正在使用之间的转换。

+0

这是一个非常大的合同;我真的很讨厌复制和粘贴大部分内容,只是为了将bool“Enabled”更改为枚举“状态”。我将坚持使用XML预处理,尽管存在问题中描述的问题,但它实际上很容易实现。 – 2009-10-04 10:28:45

4

1年后我不得不说,DataContractSerializer真的吸吮版本。它太僵硬了。这确实意味着不太可能改变的合同,然后只用特定的方式。您必须做额外的工作才能使其更快 - 例如KnownTypeAttribute。如果你需要相对较快的序列化,我只会推荐它 - 可以说,它对于它的设计非常重要。

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

现在,如果我能在这里发布...但是它是约5倍,10倍比DataContractSerializer的慢。

+0

首先感谢您发表这篇文章,我即将展开与去年一样的噩梦。我无法找到DataContractSerializer的一个很好的替代方案,我认为您的其他Serializer是专有的,因此您无法共享它? – Jambobond 2010-10-22 11:54:37

+0

@Jambobond恐怕是这样:( – 2010-10-22 16:44:46

相关问题