Persisting Custom Data Types with NHibernate

NHibernate provides native support for primitive types/enumerations only. What if I want to save something like a custom data type, say for example a System.Uri object? NHibernate provides a fairly simple way to do that which is an interface actually called IUserType. It has got a whole bunch of methods which should be implemented by your class.

    public interface IUserType
    {
        SqlType[] SqlTypes { get; }
        System.Type ReturnedType { get; }
        bool Equals( object x, object y );
        object NullSafeGet( IDataReader rs, string[] names, object owner );
        void NullSafeSet( IDbCommand cmd, object value, int index );
        object DeepCopy( object value );
        bool IsMutable { get; }
    }

The following method of the interface tells the data base type:

public SqlType[] SqlTypes
{
get
{
// We store our Uri in a single column in the database that can contain a string
SqlType[] types = new SqlType[1];
types[0] = new SqlType(DbType.String);
return types;
}
}

And this method tells the .NET type to be built for the value.

public System.Type ReturnedType
{
get { return typeof(Uri); }
}

This is how you build the .NET datatype from the value:

public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
// We get the string from the database using the NullSafeGet used to get strings
string uriString = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
// And save it in the Uri object. This would be the place to make sure that your string
// is valid for use with the System.Uri class, but i will leave that to you
Uri result = new Uri(uriString);
return result;
}

This is how you translate the value back to database type.

public void NullSafeSet(IDbCommand cmd, object value, int index)
{
// Set the value using the NullSafeSet implementation for string from NHibernateUtil
if (value == null)
{
NHibernateUtil.String.NullSafeSet(cmd, null, index);
return;
}
value = value.ToString(); // ToString called on Uri instance
NHibernateUtil.String.NullSafeSet(cmd, value, index);
}

The rest of the method are simple, and you can find them on the internet as well (where I found them :-))

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s