mardi 20 avril 2010

Clé composite, mapping et class avec Nhibernate

Il vous est peut etre déja arrivé d'essayer de mapper une table qui ne contient aucune clé primaire (ou alors qui est composé). Pour ma part, hier cela m'est arrivé !
C'est ce que je vais essayer de décrire dans les étapes suivantes.

Lors de l'execution et du mapping de NHibernate, logiquement (sans mettre de clé primaire dans votre fichier xml), vous devriez tomber sur ce message :
- “composite-id class must override Equals()”
- “composite-id class must override GetHashCode()”

Pour corriger cette erreur, il faut absoluement avoir une clé primaire. Dans notre cas, elle sera composée (de Contrat_ID et Code_Agn).

Voici notre mapping:

















Notre classe :
public class Allegement
{
    public virtual string Contrat_ID { get; set;}
    public virtual string Lot_Paie { get; set;}
    public virtual string Montant_ALLGT_1 { get; set;}
    public virtual string Code_Agn { get; set; }

    // nécessaire lors des clés composites
    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        Allegement a = obj as Allegement;
        if (a == null)
            return false;

        if (this.Contrat_ID == a.Contrat_ID && this.Code_Agn == a.Code_Agn)
            return true;
        else
            return false;
    }

    // necessaire lors des clés composites
    public override int GetHashCode()
    {
        int hash = 666; // ce que l'on veux 
        hash += (null == this.Contrat_ID ? 0 : this.Contrat_ID.GetHashCode());
        hash += (null == this.Code_Agn ? 0 : this.Code_Agn.GetHashCode());

        return hash;
    }
}}

Les élements a retenir de cet exemple sont :
- pas de mapping sans clé primaire
- la redefinition des méthodes "Equals" et "GetHashCode", des classes de bases

Pour plus d'information sur le mapping : http://nhforge.org/doc/nh/en/index.html dans la partie "5. Basic O/R Mapping"

mardi 13 avril 2010

Récupération valeur d'une séquence Oracle avec NHibernate

Bonjour à tous,

Aujourd'hui je vais vous présentez comment récupérer une valeur d'une séquence oracle (SEQ_NAME.NEXTVAL) à l'aide de NHibernate sans écrire la requête SQL. A vrai dire l'information n'est pas facile a dénicher sur le net.

Donc voici les quelques lignes de code qui permettent de récupérer la nouvelle valeur :

NHibernate.Dialect.Oracle10gDialect dial = new NHibernate.Dialect.Oracle10gDialect();
string sqlString = dial.GetSequenceNextValString("SEQ_NAME"); // génère Select SEQ_NAME.NEXVAL FROM DUAL

ISQLQuery sqlQuery = _session.CreateSQLQuery(sqlString);
return sqlQuery.UniqueResult().ToString();

C'est plutôt simple, et donc il est facile d'étendre vos objets pour rendre cette partie un peu plus générique ;)

Bonne journée à tous

mardi 6 avril 2010

Concept Objet : quelques rappels ...

Bonjour,

Aujourd'hui je vous propose un petit billet de "rappel" sur les concepts de la programmation orientée objet (POO). Qui je doit le reconnaitre m'était sorti de la tête.
En effet, je ne faisait que du "procédurale" (en asp.net c# 1.1) ... les concepts de base se sont vite oubliés.
Mais désormais je réfléchi sur les architectures (Asp.Net MVC 3.5) et force est de constater que les concepts obscures (et chiants ?) vu en cours pendant mes études, deviennent des concepts tout à fait géniaux. Dès lors ou l'on comprend réellement leur application, tout parait bien plus "naturel".

Je vais essayer de vous présenter les différentes méthodes que je côtoie actuellement. Cela me permet, d'une part d'une part de mieux appréhender le sujet, et d'autre part de le récupérer sur le blog dans le cas ou j'aurai un trou de mémoire. (ce qui arrive malheureusement)

Mots clés :

- override : notifie que la méthode (ou attribut) est réécrit/redéfini dans la classe fille
- Virtual : permet de réécrire (c'est optionnel) la méthode dans une classe fille grace au mot clé override
- abstract : force la classe fille de réecrire la méthode (override). Attention, nécessite que la classe mère soit noté abstract également.


Exemple :
public abstract class Service< T >     // "T" : Generic - Correspond a un modèle
{
   protected Repository repo;

   public virtual T FindOne(object id)
   {
      return repo.FindOne< T >(id);
   }

   public abstract void Save(T entite);
}

public class Commune_Service : Service< commune >
{
   // obligatoire : ne compile pas si elle n'est pas définie
   public override void Save(Commune entite) 
   {
      throw new NotImplementedException();
   }
}

Visual Studio vous apporte un coup de pouce :