2010-01-05 5 views
3

J'ai un objet qui utilise System.Version en tant que propriété. Je veux que cet objet soit mappé dans ma table, en stockant la version comme une chaîne. Quelle est la meilleure façon d'y parvenir avec NHibernate v1.2?mappage System.Version avec NHibernate 1.2

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

ne sais pas quoi faire avec la cartographie propery

< property name = "MyVersion" colonne = "MyVersion" not-null = "true"/>

cela me donne des erreurs disant "La tentative de GetBytes sur la colonne" MyVersion0_0_ "n'est pas valide La fonction GetBytes ne peut être utilisée que sur des colonnes de type Text, NText ou Image." Si j'utilise type = "string" dans la carte, je reçois des erreurs.

suggestions?

Répondre

4

Vous devez écrire un type d'utilisateur NHibernate, qui renvoie une valeur de propriété de type Version, mais qui persiste sous la forme d'une chaîne. Il existe une implémentation de type utilisateur squelette here qui prend en charge une partie du travail pour vous.

+0

C'est exactement ce que j'ai fait dans mon code précédemment, fonctionne bien. –

+0

Je l'ai fait dans de nombreux autres cas, mais pas Version. Si vous avez du code de travail, vous pouvez poster une réponse avec ... –

+0

cette URL ne répond pas. Quelqu'un at-il une version en cache de celui-ci? –

0

La réponse de David M est probablement la façon la plus robuste de s'y prendre. Comme alternative, vous pouvez convertir la propriété en chaîne et simplement l'utiliser. Je ne suis pas sûr de la taille du changement dans votre modèle.

2

La suggestion de David M et le lien vers l'article étaient excellents. Juste au cas où quelqu'un a des problèmes pour faire de ce site, bien que (je devais le charger dans le cache google), voici ma solution:


    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); 
     } 
    } 

et le fichier de mappage a maintenant cette propriété:

< property name = Type "MyVersion" colonne = "MyVersion" = non nulle "true" = "My.Namespace.VersionUserType, My.Assembly"/>

2

Un autre pouce pour la réponse de David M. Cependant, vous remarquerez que System.Version a un constructeur qui prend une représentation de chaîne, ainsi qu'un ToString() qui produit le même format, ainsi vous pouvez mapper la propriété comme une simple chaîne dans NHibernate et la mapper directement à un champ de chaîne privé, alors une propriété de façade typée à System.Version quelque chose comme ceci:

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

je ne vois pas cela comme une mauvaise pratique en particulier, et il est assez facile à faire. Vous devrez peut-être utiliser une propriété interne plutôt qu'un champ si vous voulez utiliser le type de chargement paresseux, mais sinon cela devrait fonctionner.