2016-03-09 52 views
0

TL,DR:我們已經在SQL DB的某些表中序列化了一些數據。不幸的是,序列化技術浪費了大量的標記字符空間。我們發現了一種新的更有效的方法:爲了保持向後兼容性,採用以下邏輯是否安全? - >當序列化發生時,它總是使用新的更有效的方式。當反序列化發生時,我們檢查字符串是使用新的序列化格式還是舊的 - >然後我們用適當的方法反序列化。這是否健壯?這可以用於生產嗎?這種方法沒有任何細微的問題嗎?ntext SQL字段中的不同字段序列化技術,同時保持向後兼容性


問候。我正在研究與SQL數據庫交互的應用程序。爲了實現特定的業務需求,我們已經在我們的數據庫表的特殊列中序列化了一些數據,類型爲ntext。基本上,在此列中的每個單元中,我們序列 「Attributo」 對象的陣列,所以typeof運算(T)是Attributo []

的 「Attributo」 的定義是這樣的:

public class Attributo 
{ 
    public virtual String Nome { get; set; } 
    public virtual String Valore { get; set; } 
    public virtual String Tipologia { get; set; } 
} 

- 反序列化讀取實際值:

XMLUtilities.Deserialize<Attributo[]>(value)); 
  • 序列化到值存儲在列(每行..):

    XMLUtilities.Serialize(attributes.ToArray());

這是輔助類,這使得使用XmlSerializer對象:

public static class XMLUtilities 
{ 
    public static T Deserialize<T>(String xmlString) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(T)); 

     using (TextReader reader = new StringReader(xmlString)) 
     { 
      return (T) serializer.Deserialize(reader); 
     } 
    } 

    public static String Serialize<T>(T xmlObject) 
    { 
     MemoryStream stream = new MemoryStream(); 

     XmlSerializer serializer = new XmlSerializer(typeof(T)); 

     XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces(); 
     xmlnsEmpty.Add("", ""); 

     serializer.Serialize(stream, xmlObject, xmlnsEmpty); 

     stream.Seek(0, SeekOrigin.Begin); 

     using (StreamReader reader = new StreamReader(stream)) 
     { 
      return reader.ReadToEnd(); 
     } 
    } 
} 

現在,這種技術的問題是它浪費了標記字符很大的空間。這是存儲在數據庫的示例串:

<?xml version="1.0"?> 
<ArrayOfAttributo> 
    <Attributo> 
    <Nome>Leakage_test_Time_prg1_p1</Nome> 
    <Valore>4</Valore> 
    <Tipologia>Single</Tipologia> 
    </Attributo> 
    <Attributo> 
    <Nome>Leakage_air_Volume_p1</Nome> 
    <Valore>14</Valore> 
    <Tipologia>Single</Tipologia> 
    </Attributo> 
</ArrayOfAttributo> 

所以,我們發現序列化的一個更簡潔的方式將這些Attributo [],產生這種輸出:

<ArrayOfA xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <A> 
    <N>Leakage_test_Time_prg1_p1</N> 
    <V>4</V> 
    <T>Single</T> 
    </A> 
    <A> 
    <N>Leakage_air_Volume_p1</N> 
    <V>14</V> 
    <T>Single</T> 
    </A> 
</ArrayOfA> 

然後,保持向後兼容性,這是核心問題我們已經實現以下邏輯:

  • 在系列化:

我們總是在序列化新的,更加簡潔時尚

  • 在反序列化:

我們檢查字符串是否開頭:

<?xml version="1.0"?> 

與否。如果是這樣的話,這是一箇舊的條目,所以我們用舊的方式對它進行反序列化。否則,我們使用新格式反序列化。

我們實現了由裝飾「Attributo」是這樣的:

[DataContract(Name = "A", Namespace= "")] 
public class Attributo 
{ 
    [DataMember(Name = "N")] 
    public virtual String Nome { get; set; } 
    [DataMember(Name = "V")] 
    public virtual String Valore { get; set; } 
    [DataMember(Name = "T")] 
    public virtual String Tipologia { get; set; } 
} 

,並通過執行以下改變我們的串行/解串方法,現在,對新序列化技術,依靠的DataContractSerializer對象:

public static T Deserialize<T>(String xmlString) 
{    
    //let's see if it's an old-style entry... 
    if (xmlString.StartsWith("<?xml version=\"1.0\"?>\r\n<ArrayOfAttributo>")) 
    { 
     try 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(T)); 

      using (TextReader reader = new StringReader(xmlString)) 
      { 
       return (T)serializer.Deserialize(reader); 
      } 
     } 
     catch { } 
    } 

    //..then it must be a new-style one 
    DataContractSerializer ser = new DataContractSerializer(typeof(T)); 

    using (Stream s = _streamFromString(xmlString)) 
    { 
     return (T) ser.ReadObject(s); 
    } 
} 

public static String Serialize<T>(T xmlObject) 
{ 
    MemoryStream stream1 = new MemoryStream(); 
    DataContractSerializer ser = new DataContractSerializer(typeof(T)); 
    ser.WriteObject(stream1, xmlObject); 
    stream1.Position = 0; 
    StreamReader sr = new StreamReader(stream1); 

    string xmlString = sr.ReadToEnd(); 

    return xmlString;  
} 

private static Stream _streamFromString(string s) 
{ 
    MemoryStream stream = new MemoryStream(); 
    StreamWriter writer = new StreamWriter(stream); 
    writer.Write(s); 
    writer.Flush(); 
    stream.Position = 0; 
    return stream; 
} 

一切似乎這種方法可以工作,但我們希望在進行任何進一步之前,評估每一個可能的風險。這是安全的用於生產?

回答

1

還有一兩件事要記住,而反序列化較早的項目:

  1. 反序列化舊條目舊式
  2. 連載舊條目在新型
  3. 保存新式串行化舊式條目,和刪除舊式串行化舊式條目。

你很好走。

相關問題