Map Enum as Int with Fluent NHibernate and NHibern

2019-02-02 23:09发布

问题:

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 );
    }
}

回答1:

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?



回答2:

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



回答3:

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.