2012-04-04 12 views
5

私は、次の表にしている:デフォルトではXML型の列をNHibernateで強く型付けされたオブジェクトのプロパティにマップするには?

class StronglyTypedData 
{ 
    public string Name {get; set;} 
    public int Number {get; set;} 
} 

、XML列:私はオブジェクトにマッピングする必要があり

CREATE TABLE [dbo].[Data] (
    [Id]   UNIQUEIDENTIFIER NOT NULL, 
    [Data] XML    NOT NULL, 
); 

class Data 
{ 
    public virtual Guid Id {get; set;} 
    public virtual StronglyTypedData Data {get; set;} 
} 

、StronglyTypedDataは何かのようですXmlDocumentプロパティにマップされていますが、マッピング時に代わりにStronglyTypedDataプロパティへのXMLシリアル化/逆シリアル化が必要です。

これを行うには何が必要ですか?

答えて

4

変換を処理するIUserTypeを書く必要があります。

実際には生のXMLからXmlDocumentに変換するXmlDocTypeから開始できます。

+0

一つ、私が知っている事私はXmlDocumentを使用して避けたいです。それは不必要なオーバーヘッドのように聞こえる。私は生のXMLと強く型付けされたオブジェクトの間で直接シリアル化/逆シリアル化することを望んでいます。つまり、XmlDocではなくXmlSerializatorを使用します。 – tishma

+1

私はあなたの実装が似たようなものになるため、XmlDocType **を例**として見ることをお勧めします。 –

+0

私は参照してください。ちょっと見てみます。ありがとう。 – tishma

8

私はこれをDiegoの投稿にコメントする予定でしたが、長すぎて構文の強調表示が必要でした。 Diegoが投稿したXmlDocTypeを変更して、厳密に型指定されたオブジェクトとの間でXMLシリアル化を使用するようにしました。

私は強い型付けを処理するために、私自身のジェネリックIUserTypeを作った:

//you'll need these at the top of your file 
//using System; 
//using System.Collections.Generic; 
//using System.Linq; 
//using System.Text; 
//using NHibernate.UserTypes; 
//using NHibernate.SqlTypes; 
//using System.Data; 
//using System.Xml; 
//using NHibernate.Type; 

[Serializable] 
public class XmlType<T> : MutableType 
{ 
    public XmlType() 
     : base(new XmlSqlType()) 
    { 
    } 


    public XmlType(SqlType sqlType) 
     : base(sqlType) 
    { 
    } 

    public override string Name 
    { 
     get { return "XmlOfT"; } 
    } 

    public override System.Type ReturnedClass 
    { 
     get { return typeof(T); } 
    } 

    public override void Set(IDbCommand cmd, object value, int index) 
    { 
     ((IDataParameter)cmd.Parameters[index]).Value = XmlUtil.ConvertToXml(value); 
    } 

    public override object Get(IDataReader rs, int index) 
    { 
     // according to documentation, GetValue should return a string, at list for MsSQL 
     // hopefully all DataProvider has the same behaviour 
     string xmlString = Convert.ToString(rs.GetValue(index)); 
     return FromStringValue(xmlString); 
    } 

    public override object Get(IDataReader rs, string name) 
    { 
     return Get(rs, rs.GetOrdinal(name)); 
    } 

    public override string ToString(object val) 
    { 
     return val == null ? null : XmlUtil.ConvertToXml(val); 
    } 

    public override object FromStringValue(string xml) 
    { 
     if (xml != null) 
     { 
      return XmlUtil.FromXml<T>(xml); 
     } 
     return null; 
    } 

    public override object DeepCopyNotNull(object value) 
    { 
     var original = (T)value; 
     var copy = XmlUtil.FromXml<T>(XmlUtil.ConvertToXml(original)); 
     return copy; 
    } 

    public override bool IsEqual(object x, object y) 
    { 
     if (x == null && y == null) 
     { 
      return true; 
     } 
     if (x == null || y == null) 
     { 
      return false; 
     } 
     return XmlUtil.ConvertToXml(x) == XmlUtil.ConvertToXml(y); 
    } 
} 

//the methods from this class are also available at: http://blog.nitriq.com/PutDownTheXmlNodeAndStepAwayFromTheStringBuilder.aspx 
public static class XmlUtil 
{ 
    public static string ConvertToXml(object item) 
    { 
     XmlSerializer xmlser = new XmlSerializer(item.GetType()); 
     using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) 
     { 
      xmlser.Serialize(ms, item); 
      UTF8Encoding textconverter = new UTF8Encoding(); 
      return textconverter.GetString(ms.ToArray()); 
     } 
    } 

    public static T FromXml<T>(string xml) 
    { 
     XmlSerializer xmlser = new XmlSerializer(typeof(T)); 
     using (System.IO.StringReader sr = new System.IO.StringReader(xml)) 
     { 
      return (T)xmlser.Deserialize(sr); 
     } 
    } 

} 

そして、最後に、あなたはこのようなあなたの列をマップするためにFluent.NHibernateを使用することができます。

public partial class MyTableEntityMap: ClassMap<MyTableEntity> 
{ 
    public MyTableEntityMap() 
    { 
     Table("MyTable"); 
     //... 

     Map(x => x.MyStronglyTypedProperty).Column("SomeXmlTypeSqlColumn").CustomType(typeof(XmlType<TypeOfMyProperty>)); 
    } 
} 
+0

おい、あなたは命の恩人です! –

関連する問題