2010-01-05 76 views
3

我有一個使用System.Version作爲屬性的對象。我希望將這個對象映射到我的表中,將該版本存儲爲一個字符串。 NHibernate v1.2的最佳做法是什麼?映射System.Version與NHibernate的1.2

public class MyClass 
{ 
    public Version MyVersion {get; set;} 
} 

不知道與屬性格式映射

<屬性名= 「MyVersion」 欄目做什麼= 「MyVersion」 不空= 「真」/ >

這給了我的錯誤說法「無效嘗試GetBytes'MyVersion0_0_'列GetBytes函數只能用於Text,NText或Image類型的列。」如果我在地圖中使用type =「string」,我會得到投射錯誤。

意見建議?

回答

4

你需要寫一個NHibernate的用戶類型,返回類型爲版本的屬性值,但仍然存在一個字符串。有一個框架用戶類型實現here,負責照顧你的一些工作。

+0

這正是我以前在我的代碼中所做的,效果很好。 – 2010-01-05 17:02:45

+0

我在許多其他情況下做過,但沒有版本。如果你已經工作的代碼,你可能想發佈一個與它的答案... – 2010-01-05 17:07:12

+0

該URL沒有響應。任何人都有它的緩存版本? – 2010-01-05 17:15:09

0

大衛M的回答可能是最強有力的方法。

作爲替代方案,您可以將財產轉換爲一個字符串,然後使用它。我不確定你的模型有多大的變化。

2

David M的建議和文章鏈接很棒。萬一別人有前往該網站,但問題(我不得不從谷歌緩存加載它),這裏是我的解決方案:


    public abstract class BaseImmutableUserType : IUserType 
    { 
     public abstract object NullSafeGet(IDataReader rs, string[] names, object owner); 
     public abstract void NullSafeSet(IDbCommand cmd, object value, int index); 
     public abstract SqlType[] SqlTypes { get; } 

     public new bool Equals(object x, object y) 
     { 
      if (ReferenceEquals(x, y)) 
      { 
       return true; 
      } 

      if (x == null || y == null) 
      { 
       return false; 
      } 

      return x.Equals(y); 
     } 

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

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

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

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

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

     public Type ReturnedType 
     { 
      get { return typeof(T); } 
     } 

     public bool IsMutable 
     { 
      get { return false; } 
     } 
    } 

    public class VersionUserType: BaseImmutableUserType 
    { 

     public override SqlType[] SqlTypes 
     { 
      get 
      { 
       return new SqlType[]{new StringSqlType()}; 
      } 
     } 

     public override object NullSafeGet(IDataReader rs, string[] names, object owner) 
     { 
      Version version = null; 
      var value = NHibernateUtil.String.NullSafeGet(rs, names) as string; 
      if (value != null) 
       version = new Version(value); 
      return version; 
     } 

     public override void NullSafeSet(IDbCommand cmd, object value, int index) 
     { 
      object valueToSet; 
      Version version = value as Version; 
      if (version != null) 
      { 
       valueToSet = version.ToString(); 
      } 
      else 
      { 
       valueToSet = DBNull.Value; 
      } 

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

和映射文件現在有此屬性:

<屬性名= 「MyVersion」 列= 「MyVersion」 不空= 「真」 TYPE = 「My.Namespace.VersionUserType,My.Assembly」/ >

2

另一個豎起大拇指對大衛·M的答案。然而,你會注意到,System.Version有一個構造函數的字符串表示,還有一個ToString()產生相同的格式,所以你可以在屬性映射爲NHibernate的一個簡單的字符串,並將其直接映射到一個私人串場,然後鍵入到System.Version這樣的一個門面屬性:

public System.Version Version 
{ 
    get { return new System.Version(_versionAsString); } 
    set { _versionAsString = value.ToString(); } 
} 

我不認爲這是不好的做法,尤其是,它是很容易的事情。你可能需要使用內部屬性而不是字段,如果你要代理類型的延遲加載,但否則它應該工作。