2013-02-19 42 views
0

我有一個名爲「Test」的屬性類型爲「ObservableDictionary」的DTO對象,這也是可序列化的!NHibernate - 映射一個複雜類型,以便序列化爲字符串

DTO字段「Test」現在映射到類型爲nvarchar(max)的Datasfield「Test」。

當我保存並加載時,一切正常,但數據庫中的序列化不可讀,它充滿了特殊的字符。

所以我想知道,是否有可能告訴NHibernate使用XMLSerializer?

+0

看這個http://blog.xebia.com/2009/ 11/09 /理解和寫作 - hibernate-user-types /它會讓你開始,你想要的東西是一個自定義用戶類型 – Rippo 2013-02-19 11:39:23

+0

實現這樣一個簡單的任務是如此複雜? – 2013-02-19 12:30:40

+0

我不會說它是一個簡單的任務,我認爲它非常棒,NHibernate是如此的可擴展性。很高興你有答案。 – Rippo 2013-02-19 13:03:57

回答

0

好的,我明白了!在Rippo的幫助下!

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Text; 
using NHibernate; 
using NHibernate.SqlTypes; 
using NHibernate.UserTypes; 

namespace MCC.Common.DL.BaseObjects 
{ 
    public class SerializableUserType<originalType> : IUserType 
    { 
     public SqlType[] SqlTypes 
     { 
      get 
      { 
       SqlType[] types = new SqlType[1]; 
       types[0] = new SqlType(DbType.String); 
       return types; 
      } 
     } 

     public System.Type ReturnedType 
     { 
      get { return typeof(originalType); } 
     } 

     public new bool Equals(object x, object y) 
     { 
      if (x == null) 
      { 
       return false; 
      } 
      else 
      { 
       return x.Equals(y); 
      } 
     } 

     public int GetHashCode(object x) 
     { 
      return x.GetHashCode(); 
     } 

     public object NullSafeGet(IDataReader rs, string[] names, object owner) 
     { 
      string txt = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]); 
      return StringSerializer<originalType>.DeSerialize(txt); 
     } 

     public void NullSafeSet(IDbCommand cmd, object value, int index) 
     { 
      if (value == null) 
      { 
       NHibernateUtil.String.NullSafeSet(cmd, null, index); 
       return; 
      } 
      var wrt = StringSerializer<originalType>.Serialize((originalType)value); 

      NHibernateUtil.String.NullSafeSet(cmd, wrt, index); 
     } 

     public object DeepCopy(object value) 
     { 
      if (value == null) return null; 
      return StringSerializer<originalType>.DeSerialize(StringSerializer<originalType>.Serialize((originalType)value));    
     } 

     public bool IsMutable 
     { 
      get { return false; } 
     } 

     public object Replace(object original, object target, object owner) 
     { 
      return original; 
     } 

     public object Assemble(object cached, object owner) 
     { 
      return cached; 
     } 

     public object Disassemble(object value) 
     { 
      return value; 
     } 
    } 
} 

,這我流利的使用,如:

Map(x => x.ScriptedTagScript).CustomType(typeof(SerializableUserType<ObservableDictionary<string, string>>)); 

而且你需要這個輔助類:

public class StringSerializer<T> 
{ 
    public static string Serialize(T obj) 
    { 
     if (obj == null) 
      return string.Empty; 

     // XML-Serialisieren in String 
     XmlSerializer serializer = new XmlSerializer(obj.GetType()); 

     // Serialisieren in MemoryStream 
     MemoryStream ms = new MemoryStream(); 

     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.OmitXmlDeclaration = true; 
     settings.Indent = true; 

     XmlWriter writer = XmlWriter.Create(ms, settings); 

     XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
     namespaces.Add(string.Empty, string.Empty); 

     serializer.Serialize(writer, obj, namespaces); 

     // Stream in String umwandeln 
     StreamReader r = new StreamReader(ms); 
     r.BaseStream.Seek(0, SeekOrigin.Begin); 

     return r.ReadToEnd(); 
    }   

    public static T DeSerialize(string txt) 
    { 
     T retVal = default(T); 
     if (string.IsNullOrEmpty(txt)) 
     { 
      return retVal; 
     } 

     try 
     { 
      XmlSerializer ser = new XmlSerializer(typeof (T)); 
      StringReader stringReader = new StringReader(txt); 
      XmlTextReader xmlReader = new XmlTextReader(stringReader); 
      retVal = (T) ser.Deserialize(xmlReader); 
      xmlReader.Close(); 
      stringReader.Close(); 
     } 
     catch (Exception) 
     { 
     } 

     return retVal; 
    }   
} 
相關問題