NHibernate Mapping to System.Drawing.Color
In my POCO (Plain Old CLR Object) class, I had a property for FontColor that is of type System.Drawing.Color. I wanted this to map to an HTML string value in the database. i.e. #ffffff
Basically, I wanted to do a type conversion from #ffffff to System.Drawing.Color. At fist I didn’t realize that this sort of type conversion was built-in to NHibernate via the interface IUserType. I thought you had to use you new custom type in the POCO, but I found that you can just use the IUserType implementation to map to the native .NET type.
Here is how I did it…
First, create the custom type that implements IUserType. This will be used to do the type conversion from string to Color.
public class ColorUserType : IUserType { public object Assemble( object cached, object owner ) { return cached; } public object DeepCopy( object value ) { return value; } public object Disassemble( object value ) { return value; } 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 == null ? typeof( Color ).GetHashCode() + 473 : x.GetHashCode(); } public bool IsMutable { get { return true; } } public object NullSafeGet( IDataReader rs, string[] names, object owner ) { var obj = NHibernateUtil.String.NullSafeGet( rs, names[0] ); if( obj == null ) { return null; } return ColorTranslator.FromHtml( (string)obj ); } public void NullSafeSet( IDbCommand cmd, object value, int index ) { if( value == null ) { ( (IDataParameter)cmd.Parameters[index] ).Value = DBNull.Value; } else { ( (IDataParameter)cmd.Parameters[index] ).Value = ColorTranslator.ToHtml( (Color)value ); } } public object Replace( object original, object target, object owner ) { return original; } public Type ReturnedType { get { return typeof( Color ); } } public SqlType[] SqlTypes { get { return new[] { new SqlType( DbType.StringFixedLength ) }; } } }
Next, create the POCO.
public class MyClass { public int Id { get; protected set; } public Color FontColor { get; set; } }
Next, create the mapping file. I’m using FluentNhibernate here.
public class MyClassMap : ClassMap<MyClass> { public MyClassMap() { SetupMapping(); } private void SetupMapping() { Id( m => m.Id ); Map( m => m.FontColor ).CustomTypeIs<ColorUserType>(); } }
Now when you get an instance of MyClass from NHibernate, the string color stored in the database will be converted to a System.Drawing.Color.