序列化和版本控制

Cap*_*mic 5 .net c# versioning serialization

我需要将一些数据序列化为字符串.然后将该字符串存储在特殊列SerializeData中的DB中.

我创建了用于序列化的特殊类.

[Serializable]
public class SerializableContingentOrder
{
    public Guid SomeGuidData { get; set; }
    public decimal SomeDecimalData { get; set; }
    public MyEnumerationType1 EnumData1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

连载:

protected override string Serialize()
{
    SerializableContingentOrder sco = new SerializableContingentOrder(this);

    MemoryStream ms = new MemoryStream();
    SoapFormatter sf = new SoapFormatter();
    sf.Serialize(ms, sco);
    string data = Convert.ToBase64String(ms.ToArray());
    ms.Close();
    return data;
}
Run Code Online (Sandbox Code Playgroud)

反序列化:

protected override bool Deserialize(string data)
{
    MemoryStream ms = new MemoryStream(Convert.FromBase64String(data).ToArray());
    SoapFormatter sf = new SoapFormatter();

    SerializableContingentOrder sco = sf.Deserialize(ms) as SerializableContingentOrder;
    ms.Close();
    return true;
}
Run Code Online (Sandbox Code Playgroud)

现在我想要版本控制支持.如果我换班,会发生什么SerializableContingentOrder.我希望将来能够添加新字段.

我是否必须切换到DataContract序列化?请给我简短的片段?

Mar*_*ell 11

极力主张存储BinaryFormatterSoapFormatter数据库中的数据; 它是:

  • 不容忍版本
  • 不是平台独立的

BinaryFormatter可以在.NET程序集之间进行数据传输(推送),但我建议使用更可预测的序列化程序.DataContractSerializer是一个选项(如JSONXmlSerializer),但我不会使用NetDataContractSerializer所有上述同样的原因.我受到诱惑而使用protobuf网,因为这是一个已知的有效的格式高效的二进制,独立于平台和版本宽容!

例如:

[DataContract]
public class SerializableContingentOrder
{
    [DataMember(Order=1)] public Guid SomeGuidData { get; set; }
    [DataMember(Order=2)] public decimal SomeDecimalData { get; set; }
    [DataMember(Order=3)] public MyEnumerationType1 EnumData1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

连载:

protected override string Serialize()
{
    SerializableContingentOrder sco = new SerializableContingentOrder(this);   
    using(MemoryStream ms = new MemoryStream()) {
        Serializer.Serialize(ms, sco);
        return Convert.ToBase64String(ms.ToArray());
    }
}
Run Code Online (Sandbox Code Playgroud)

反序列化:

protected override bool Deserialize(string data)
{
    using(MemoryStream ms = new MemoryStream(Convert.FromBase64String(data)) {
        SerializableContingentOrder sco =
               Serializer.Deserialize<SerializableContingentOrder>(ms)
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不应该提倡反对存储而不是*不存储吗?:)不要错误的方式,英语不是我的母语,因此问题. (2认同)

Den*_*nis 7

You have two options if you want to support versioning. Use DataContracts or use Version Tolerant Serialization. Both are valid.

DataContacts handle the addition and removal of fields automatically. See Data Contact Versioning and Best Practices: Data Contract Versioning for more information.

DataContact Example

[DataContract]
public class ContingentOrder
{
    [DataMember(Order=1)]
    public Guid TriggerDealAssetID;

    [DataMember(Order=2)]
    public decimal TriggerPrice;

    [DataMember(Order=3)]
    public TriggerPriceTypes TriggerPriceType;

    [DataMember(Order=4)]
    public PriceTriggeringConditions PriceTriggeringCondition;

}
Run Code Online (Sandbox Code Playgroud)

Version Tolerant Serialization Example

// Version 1
[Serializable]
public class SerializableContingentOrder
{
    public Guid TriggerDealAssetID;
    public decimal TriggerPrice;
    public TriggerPriceTypes TriggerPriceType;
    // Omitted PriceTriggeringCondition as an example
}

// Version 2 
[Serializable]
public class SerializableContingentOrder
{
    public Guid TriggerDealAssetID;
    public decimal TriggerPrice;
    public TriggerPriceTypes TriggerPriceType;

    [OptionalField(VersionAdded = 2)]
    public PriceTriggeringConditions PriceTriggeringCondition;

    [OnDeserializing]
    void SetCountryRegionDefault (StreamingContext sc)
    {
        PriceTriggeringCondition = /* DEFAULT VALUE */;
    }

}
Run Code Online (Sandbox Code Playgroud)

More information on Version Tolerant Serialization. Especially take note of the best-practices at the bottom of the page.

Note, DataContracts were introduced in .NET 3.5 so you may not have that option if you need to target .NET 2.0.

HTH,