NHibernate Image User Type
Supose you want to have in your domain model a property which is of type System.Drawing.Image. On SQL Server, you would map this as a column of type IMAGE, and on your domain model you would define it like this:
public
virtual System.Drawing.Image Image{
get;
set;
}
In order to use it with NHibernate, you must define a custom user type, by implementing the NHibernate.UserTypes.IUserType interface. We write a ImageUserType class and register it at the property definition in the .hbm.xml file:
<
property name="Image" column="`Image`" type="ImageUserType, MyAssembly"/>And here is the code;
using System;
using System.Collections.Generic;using
System.Linq;using
System.Text;using
NHibernate.UserTypes;using
System.Data;using
NHibernate.SqlTypes;using
System.Drawing;using
NHibernate;using
System.IO;using
System.Drawing.Imaging;public class ImageUserType: IUserType
{
public Object Assemble(Object cached, Object owner)
{
return (cached);
}
public Object DeepCopy(Object value)
{
if (value == null)
{
return (null);
}
else
{
return ((value as ICloneable).Clone());
}
}
public Object Disassemble(Object value)
{
return (value);
}
public Int32 GetHashCode(Object x)
{
return (x != null ? x.GetHashCode() : 0);
}
public Boolean IsMutable
{
get
{
return (false);
}
}
public Object NullSafeGet(IDataReader rs, String [] names, Object owner)
{
Byte [] data = NHibernateUtil.Binary.NullSafeGet(rs, names [ 0 ]) as Byte [];
if (data != null)
{
using (Stream stream = new MemoryStream(data))
{
Image image = Image.FromStream(stream);
return (image);
}
}
else
{
return (null);
}
}
public void NullSafeSet(IDbCommand cmd, Object value, Int32 index)
{
if (value == null)
{
NHibernateUtil.Binary.NullSafeSet(cmd, null, index);
}
else
{
using (MemoryStream stream = new MemoryStream())
{
Image image = value as Image;
image.Save(stream, ImageFormat.Png);
NHibernateUtil.String.NullSafeSet(cmd, stream.GetBuffer(), index);
}
}
}
public Object Replace(Object original, Object target, Object owner)
{
return (original);
}
public Type ReturnedType
{
get
{
return (typeof(Image));
}
}
public SqlType [] SqlTypes
{
get
{
return (new SqlType [] { new SqlType(DbType.Binary) });
}
}
Boolean IUserType.Equals(Object o1, Object o2)
{
return (Object.Equals(o1, o2));
}
}
This saves the image object as an array of bytes (in PNG format, to use compression) and loads it into an System.Drawing.Image. The image is immutable, so a lot of methods are quite simple.
I think the code is easily understandable, but if you have problems, let me know!