用于序列化数据的实体已更改。如何为新实体升级序列化数据?

时间:2011-01-14 19:00:55

标签: c# serialization refactoring model domain-driven-design

我有一堆简单的实体实例,我已将其序列化为文件。在将来,我知道这些实体的结构(也就是说,我可能会将Name重命名为Header或者其他东西)。问题是,我不想丢失我在所有这些旧文件中保存的数据。

的正确方法是什么?
  1. 将旧实体的数据加载到新实体
  2. 升级旧文件,以便它们可以与新实体一起使用
  3. 注意:我认为我坚持使用二进制序列化,而不是xml序列化。

    提前致谢!

    编辑:所以我对我所描述的案例有一个答案。我可以使用dataContractSerializer并执行类似

    的操作
    [DataMember("bar")]
    private string foo;
    

    并更改代码中的名称并保留用于序列化的名称。但是以下其他案例呢?

    1. 原始实体具有可以序列化的新成员
    2. 删除原始实体中的某些序列化成员
    3. 一些成员实际上已经改变了函数(假设原始类有一个FirstName和LastName成员,并且它已被重构为只有一个FullName成员,它将两者结合起来)
    4. 要处理这些,我需要某种解释器/翻译器反序列化类,但我不知道应该使用什么

3 个答案:

答案 0 :(得分:2)

我使用过BinaryFormatter,然后注意这是一个字段序列化程序,而不是属性序列化程序;你可以通过不改变字段名称来破解它。除非它是一个自动实现的属性,在这种情况下你不能。

老实说,如果你想要灵活地改变类型,BinaryFormatter是一个糟糕的选择。基于合同的序列化器在这里更加灵活。例如,XmlSerializer和DataContractSerializer允许您通过属性控制名称。

如果你想要二进制文件,我会选择protobuf-net(也许是因为我写了...) - 这里 没有名字 - 只是数字标识符。但protobuf格式是由Google 专门设计的,可以轻松升级API。

当然,您也可以将DTO视为永久合同;在这种情况下考虑使用v1 DTO,v2 DTO等。不是我倾向于自己做的方式,但绝对是一种选择。

答案 1 :(得分:0)

无论您使用何种序列化机制,重命名属性都是一个重大变化。二进制序列化的问题在于,您无法轻松文件升级到新格式,这对于文本格式序列化来说将更容易。

答案 2 :(得分:0)

你需要编写一个程序

  • 将数据反序列化为旧版本的实体
  • 将旧版本的实体转换为新版本的实体
  • 将新版本的实体序列化回文件。

如果您已将其序列化为XML,则可以编写XSLT以直接进行所需的更改。