views:

54

answers:

2

Hi everyone,

I have a simple ASP.NET MVC web application that uses NHibernate with FluentNHibernate's auto mapping feature for its data access. I have encountered a scenario in which I would like NHibernate to persist some classes as binary data.

For example, I have something similar to this:

public class User
{
    ...

    // This field will be persisted
    public virtual byte[] PortraitData { get; set; }

    // This method will get me what I'm actually interested in
    public virtual Image GetPortrait()
    {
        return SerializationHelper.Deserialize<Image>(PortraitData);
    }
}

(I leave the implementation of the SerializationHelper class to the reader's imagination. It doesn't do anything complicated, just serializes and deserializes data into byte arrays and back.)

I would like to change the above code to this:

public class User
{
    ...

    public virtual Image Portrait { get; set; }
}

So basically I wish to tell (Fluent)NHibernate that it should persist some classes (specified by me) by serializing them into a binary field with the name of the actual property.
(In the above case, I would like it to serialize the Image into a varbinary field called Portrait.)

The actual scenario I have is a bit more complicated than this, but this example demonstrates very well what I want to achieve. (Meaning: the System.Drawing.Image class is not the only one I'm interested in serializing.)

I know there must be some kind of configuration in either Fluent or NHibernate itself that allows to do exactly this, but I couldn't figure it out. Could you please tell me how to do this?

Thanks in advance for your help!

A: 

You have to implement IUserType.

Then it's just a matter of telling NH to use it for that property.

In xml it's type="QualifiedName"; look for the FNH equivalent.

Diego Mijelshon
+1  A: 

The key is an implementation of IUserType, which is essentially an interface you use to translate back and forth from a POCO type to a SQL type. I use it to translate enumerations <-> custom string values in the database. Take a look at the NHibernate code for YesNoType, which translates back and forth between true/false booleans POCO types to "YES"/"NO" SQL varchar types.

To utilize this in Fluent NHibernate, you can invoke the .CustomType() method on the Map method, where T is the class that implements IUserType. I think you could create a convention such that all Image properties would use the implementing class, rather than having to define it on a per-property basis, but I'm not familiar with that part of Fluent NHibernate.

e.g. Map(x => x.Portrait, "PORTRAIT_DATA").CustomType();

Rich
+1 Great response, explains many things. :)
Venemo
I found the Fluent cnventon for this: http://wiki.fluentnhibernate.org/Available_conventions#UserTypeConvention.3CT.3E
Venemo