views:

4946

answers:

5

Question says it all really, the default is for it to map as a string but I need it to map as an int.

I'm currently using PersistenceModel for setting my conventions if that makes any difference. Thanks in advance.

Update Found that getting onto the latest version of the code from the trunk resolved my woes.

A: 

You could create an NHibernate IUserType, and specify it using CustomTypeIs<T>() on the property map.

James Gregory
+19  A: 

So, as mentioned, getting the latest version of Fluent NHibernate off the trunk got me to where I needed to be. An example mapping for an enum with the latest code is:

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));

The custom type forces it to be handled as an instance of the enum rather than using the GenericEnumMapper<TEnum>.

I'm actually considering submitting a patch to be able to change between a enum mapper that persists a string and one that persists an int as that seems like something you should be able to set as a convention.


This popped up on my recent activity and things have changed in the newer versions of Fluent NHibernate to make this easier.

To make all enums be mapped as integers you can now create a convention like so:

public class EnumConvention : IUserTypeConvention
{
    public bool Accept(IProperty target)
    {
        return target.PropertyType.IsEnum;
    }

    public void Apply(IProperty target)
    {
        target.CustomTypeIs(target.PropertyType);
    }

    public bool Accept(Type type)
    {
        return type.IsEnum;
    }
}

Then your mapping only has to be:

Map(quote => quote.Status);

You add the convention to your Fluent NHibernate mapping like so;

Fluently.Configure(nHibConfig)
    .Mappings(mappingConfiguration =>
    {
        mappingConfiguration.FluentMappings
            .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
    })
    ./* other configuration */
Garry Shutler
with "int mode" as the default. Who persists enums as strings?!
Andrew Bullock
Could be a legacy database with string values already in there
Hainesy
+1 hainesy. @ Andrew Bullock: answer to your question: anyone who deals with real world databases.
Sky Sanders
+30  A: 

The way to define this convention changed sometimes ago, it's now :

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}
Julien
This is the correct answer for the most recent version of fluent nhibernate
Sean Chambers
Bump. ^^ What Sean said.
Martin Aatmaa
Thanks, I wish this could be the accepted answer now.
Aaron Smith
+2  A: 

Don't forget about nullable enums (like ExampleEnum? ExamplePoperty)! They need to be checked separately. This is how it's done with the new FNH style configuration:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum ||
            (x.Property.PropertyType.IsGenericType && 
             x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
             x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
            );
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}
SztupY
+4  A: 

this is how I've mapped a enum property with an int value:

Map(x => x.Status).CustomType(typeof(Int32));

works for me!

Felipe
Thanks for providing the simplest answer
Mike
My only qualm with this is that you have to remember to apply it to every enum. That's what the conventions were created for.
Garry Shutler
This works for reading but failed when I tried a criteria query. Setting up a convention (see answer to this question) did work in all cases I tried though.
Thomas Bratt