In Mappare enumerati in campi stringa con NHibernate è descritto come mappare una proprietà di tipo enumerato su una colonna di tipo stringa con NHibernate. La mappatura di default tuttavia appare poco applicabile a casi reali in quanto il valore del campo in tabella sarà uguale al nome del valore dell'enum espresso in formato stringa. Partendo dall'esempio del tip precedente, vedremo come personalizzare la mappatura.
Come primo passo estenderemo la classe base per crearne una nuova che applichi il pattern strategy sul mapping dell'enumerato. In realtà già ora i metodi "GetValue" e "ToString" sono pensati per centralizzare l'operazione di mapping ma analizzando il codice ci si accorge che non tutti i casi d'uso seguono tale linea guida: occorre quindi applicare alcune ridefinizioni per correggere il problema.
public class EnumCustomType<T> : EnumStringType
{
//Il costruttore richiede che gli si indichi la lunghezza del campo
//il tipo di enumerato verrà indicato dal tipo che chiuderà la classe generica.
public EnumCustomType(int length) : base(typeof(T), length) { ;}
public override object GetInstance(object code)
{
return GetValue(code);
}
public override void Set(System.Data.IDbCommand cmd, object value, int index)
{
IDataParameter parameter = (IDataParameter)cmd.Parameters[index];
parameter.Value = ToString(value);
}
public override object Get(System.Data.IDataReader rs, int index)
{
return GetValue(rs[index]);
}
}
Segue un'applicazione pratica della classe appena definita all'enumerato Sesso: il semplice override dei metodi "GetValue" e "ToString" consentirà di focalizzare l'implementazione della classe sulle sole problematiche di mapping.
public class SessoType : EnumCustomType<Sesso>
{
public SessoType(): base(1){;}
public override object GetValue(object code)
{
string string_value = (string) code;
switch (string_value)
{
case "M": return Sesso.Maschio;
case "F": return Sesso.Femmina;
default: throw new NotSupportedException();
}
}
public override string ToString(object value)
{
Sesso enum_value = (Sesso)value;
switch (enum_value)
{
case Sesso.Femmina: return "F";
case Sesso.Maschio: return "M";
default: throw new NotSupportedException();
}
}
}
//...
//Mappatura del campo nel file .hbm.xml
<property name="Sesso" column="SESSO" type="MyNamespace.SessoType,MyAssembly"/>
In riferimento a NHibernate 1.2.0.4.