2013-02-19 64 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; 
    }   
} 
相关问题