Question

J'ai une base de données Oracle et l'un des champs est un champ de plage de dates. Il est essentiellement stocké dans la base de données sous la forme d'un fichier VARCHAR (40) au format AAAA / MM / JJ-AAAA / MM / JJ. Je veux le mapper dans nHibernate à une classe personnalisée que j'ai créée comme ceci

public class DateTimeRange
{
    public DateTimeRange(DateTime fromTime, DateTime toTime)
    {
        FromTime = fromTime;
        ToTime = toTime;
    }

    public override string ToString()
    {
        return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss"));
    }

    public DateTime FromTime { get; set; }

    public DateTime ToTime { get; set; }
}

Comment mapper des classes personnalisées comme celle-ci?

Était-ce utile?

La solution

Vous devez implémenter votre propre IUserType.

Voir ce article de blog pour plus de détails. Je collerai également la section pertinente ci-dessous au cas où le blog disparaîtrait.

Dans NHibernate, un type de mappage personnalisé est une classe dérivée des interfaces IUserType ou ICompositeUserType. Ces interfaces contiennent plusieurs méthodes qui doivent être implémentées, mais pour les besoins de cette page, nous allons nous concentrer sur deux d’entre elles. Considérer ce qui suit.

  public class TypeClassUserType : IUserType
  {


    object IUserType.NullSafeGet(IDataReader rs, 
      string[] names, 
     object owner) {

     string name = NHibernateUtil.String.NullSafeGet(rs, 
     names[0]) as string;

     TypeClassFactory factory = new TypeClassFactory();
     TypeClass typeobj = factory.GetTypeClass(name);
     return typeobj;
   }

    void IUserType.NullSafeSet(IDbCommand cmd, 
    object value, 
     int index) {

      string name = ((TypeClass)value).Name;
     NHibernateUtil.String.NullSafeSet(cmd, name, index);
    }
  }

Après avoir créé cette classe, je peux maintenant mapper explicitement l'association entre ActualClass et TypeClass en tant que propriété simple sur le mappage ActualClass.

<property
  name="Type"
  column="TypeName"
  type="Samples.NHibernate.DataAccess.TypeClassUserType, 
        Samples.NHibernate.DataAccess" />

Dans la mesure où NHibernate est en train de sauvegarder une instance de ActualType, il charge et crée une nouvelle instance de TypeClassUserType et appelle la méthode NullSafeSet. Comme vous pouvez le constater dans le corps de la méthode, j'extrais simplement le nom de la propriété mappée (transmise en tant que paramètre value) et définissais le nom extrait en tant que valeur du paramètre à définir dans la base de données. Le résultat net est que bien que la propriété Type de ActualClass soit TypeClass dans le modèle de domaine, seule la propriété Name de l'objet TypeClass est stockée dans la base de données. L'inverse est également vrai. Lorsque NHibernate charge une instance de ActualType à partir de la base de données et qu'il trouve une propriété de mon type de mappage personnalisé, il charge mon type personnalisé et appelle la méthode NullSafeGet. Comme vous pouvez le constater, ma méthode obtient le nom des données renvoyées, appelle ma fabrique flyweight pour obtenir la bonne instance de TypeClass, puis renvoie cette instance. Le processus de résolution de type a lieu de manière transparente dans mes classes d'accès aux données (et même à NHibernate lui-même).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top