16

I have a data access class with an Enum called Salutation:

 public enum Salutation
  {
    Unknown = 0,
    Dame = 1,
    etc
    Mr = 5,
    etc
  }

I am peristing the class with NHibernate, and up until this morning I was using .hbm.xml files for mapping. However, I've now switched to using Fluent NHibernate, but loading instances of the class fails with (for example):

[HibernateException: Can't Parse 5 as Salutation]

As you can see, 5 should be parseable as a Salutation (assuming 5 is an int, it's not possible to tell from the error message).

Anyone know what's going on here?

Thanks

David

David
  • 15,750
  • 22
  • 90
  • 150

3 Answers3

35

This is much easier than I thought.

Map(x => x.WhateverThePropertyNameIs).CustomType(typeof(MyEnumeration));
David
  • 15,750
  • 22
  • 90
  • 150
  • Otherwise NHibernate will assume that the enum is represented in the database by its string value, rather than by its int value. – David Aug 08 '11 at 12:55
  • 2
    Ah, OK. That looks like an odd choice of default to me. – svick Aug 08 '11 at 19:14
1

Another option is using, EnumConvention:

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestApp
{
    using FluentNHibernate.Conventions;
    using FluentNHibernate.Conventions.AcceptanceCriteria;
    using FluentNHibernate.Conventions.Inspections;
    using FluentNHibernate.Conventions.Instances;

    public class EnumConvention :
        IPropertyConvention,
        IPropertyConventionAcceptance
    {
        #region IPropertyConvention Members

        public void Apply(IPropertyInstance instance)
        {
            instance.CustomType(instance.Property.PropertyType);
        }

        #endregion

        #region IPropertyConventionAcceptance Members

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

        #endregion
    }
}

To use this enumconvention:

...
var fluentCfg = Fluently.Configure().Database(cfg).Mappings(
                    m => m.FluentMappings.AddFromAssemblyOf<SomeObjectMap>().Conventions.Add<EnumConvention>());
...

And in mapping file,

Map(x => x.SomeEnumField);
iknowitwasyoufredo
  • 605
  • 1
  • 10
  • 19
0

Since the most accepted answer does still fail with same error, here my solution:

public class ConventionName : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(property => property.Type == typeof(FluentNHibernate.Mapping.GenericEnumMapper<EnumNameHere>));
    }

    public void Apply(IPropertyInstance instance)
    {
        instance.CustomType<EnumNameHere>();
    }
}
Trivalik
  • 80
  • 7