Archive for June 2009

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.