9

我有使用二进制序列化为以下类存储的数据:

[Serializable]
public abstract class BaseBusinessObject
{
    private NameValueCollection _fieldErrors = new NameValueCollection();

    protected virtual NameValueCollection FieldErrors
    {
        get { return _fieldErrors; }
        set { _fieldErrors = value; }
    }

    ...
}

在某些时候,课程更改为:

[Serializable]
public abstract class BaseBusinessObject
{
    private Dictionary<string, string> _fieldErrors = new Dictionary<string, string>();

    protected virtual Dictionary<string, string> FieldErrors
    {
        get { return _fieldErrors; }
        set { _fieldErrors = value; }
    }

    ...
}

这会导致反序列化旧数据的问题。

我的第一个想法是实现ISerializable,但是这个类有许多属性以及数百个继承类,我也必须实现它。

我想在反序列化期间更改旧数据以匹配当前结构,或者有一种干净的方式来升级旧数据。

4

4 回答 4

5

fieldErrors以不同的名称添加新的 _ ,比如说_fieldErrors2,然后 make [Optional]。然后实现一个[OnDeserialized]将数据复制_fieldErrors_fieldErrors2(如果存在)的方法,并清除 _fieldErrors。

于 2009-08-11T15:11:59.093 回答
3

如果数据仅在内部使用,我的第一个想法是编写一些简单的一次性代码,使用旧的“NameValueCollection”反序列化二进制数据,将其映射到字典并重新序列化。即使处理所有数据需要几天时间,在新代码上实施补丁以支持旧数据似乎也不值得。

即使它不仅在内部使用,导入器似乎也是最简单的方法。

于 2009-08-11T14:52:03.963 回答
2

除了 OlivierD 的好建议之外,我建议您定义这两个类,但最初尝试反序列化为当前版本。在您的 catch 块中,将其反序列化为旧版本,然后将其升级到当前版本并保存回来。当不存在旧版本的实例时,您可以删除代码。

于 2009-08-11T14:59:57.507 回答
0

在研究了几个选项后,我得出以下结论:

理想情况下,我将能够访问原始值NameValueCollection并将其手动转换为Dictionary<string, string>. 做到这一点的唯一方法是实现ISerializable,但这带来了两个主要问题:匹配遗留数据的命名和包含所有继承类(其中有数百个)的序列化逻辑。

实际上,这让我陷入了困境。幸运的是,我能够确定该字段实际上仅用作表单验证错误的摘要,并且不应该首先被序列化,因此我将其排除在序列化之外。

于 2009-08-11T20:31:18.670 回答