23
votes

I used this How do you map an enum as an int value with fluent NHibernate? to map in the past but I've recently upgraded to NHibernate 3 and this doesn't seem to work anymore. I've put breakpoints in my EnumConvention class and they're not being hit. The query that is hitting the database has the enum as a string which is the default configuration.

How does this work with NHibernate 3?

Update

Here is part of the mapping file that is generated:

<property name="ComponentType" type="FluentNHibernate.Mapping.GenericEnumMapper`1[[...ComponentType, ..., Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], FluentNHibernate, Version=1.1.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880">
  <column name="ComponentTypeId" />
</property>

It doesn't seem right that it would be using a GenericEnumMapper when an IUserTypeConvention is specified for enums.

Here is my convention:

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

    public void Apply( IPropertyInstance instance )
    {
        instance.CustomType( instance.Property.PropertyType );
    }
}
3
I really dnt see what you stand to gain out of this exercise but this might have been removed for a reason as they dint find a need to keep it aroundBaz1nga
I don't see anywhere that it has gone away, it just doesn't seem to work anymore. How else can this be done then? Doing Map( ... ).CustomType<int>() doesn't work. It causes problems. I will try doing a custom IUserType and see if that works for now.Josh Close
Im saying do you have any reason for storing it as a int instead of enum?With mem nt a prob i really dnt see a reason.. string enums are code safe..Baz1nga
Ah. It's actually in the database as a table, so the int for the enum lines up with the id of the table row. The table is fixed and can't be changed, so I wanted to use an enum for it.Josh Close

3 Answers

46
votes

Simply doing Map( m => m.MyEnum ).CustomType<MyEnum>() seems to work just fine now.

If anyone knows why IUserTypeConvention doesn't work with Fluent NHibernate in NHibernate 3, I'd still like to know why. Maybe it's because mapping the custom type to the enum works now, but why wasn't it removed from the lib then?

1
votes

I'm running into a similar problem with Nhibernate 3.0GA and FluentNh (rebuild with the latest NH version). UserTypeConventions are not getting registered properly.

problem described here : http://groups.google.com/group/nhusers/browse_thread/thread/c48da661f78bfad0

0
votes

You should inherit your convention not from IUserTypeConvention, but from FluentNHibernate.Conventions.UserTypeConvention.

For example, this is the exact convention I use to map boolean and nullable booleans to a custom type called UserTrueFalseType:

    /// <summary>
/// Convention: Boolean fields map to CHAR(1) T/F/Null
/// </summary>
public class BooleanTrueFalseConvention : FluentNHibernate.Conventions.UserTypeConvention<UserTrueFalseType>
{
    /// <summary>
    /// Accept field type criteria
    /// </summary>
    /// <param name="criteria"></param>
    public override void Accept(FluentNHibernate.Conventions.AcceptanceCriteria.IAcceptanceCriteria<FluentNHibernate.Conventions.Inspections.IPropertyInspector> criteria)
    {
        criteria.Expect(instance =>
            instance.Property.PropertyType.Equals(typeof(System.Boolean))
            ||
            instance.Property.PropertyType.Equals(typeof(System.Nullable<System.Boolean>))
        );
    }
}

This works with NH 3.3 and the last version of Fluent.