0
votes

I have a Sharp Architecture based app using Fluent NHibernate with Automapping. I have the following Enum:

    public enum Topics
    {
        AdditionSubtraction = 1,
        MultiplicationDivision = 2,
        DecimalsFractions = 3
    }

and the following Class:

    public class Strategy : BaseEntity
    {
        public virtual string Name { get; set; }
        public virtual Topics Topic { get; set; }
        public virtual IList Items { get; set; }

    }

If I create an instance of the class thusly:

Strategy s = new Strategy { Name = "Test", Topic = Topics.AdditionSubtraction };

it Saves correctly (thanks to this mapping convention:

    public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance
    {
        public void Apply(FluentNHibernate.Conventions.Instances.IPropertyInstance instance)
        {
            instance.CustomType(instance.Property.PropertyType); 
        }

        public void Accept(FluentNHibernate.Conventions.AcceptanceCriteria.IAcceptanceCriteria criteria)
        {
            criteria.Expect(x => x.Property.PropertyType.IsEnum); 
        }
    }

However, upon retrieval (when SQLite is my db) I get an error regarding an attempt to convert Int64 to Topics.

This works fine in SQL Server.

Any ideas for a workaround?

Thanks.

2

2 Answers

3
votes

Actually, it is possible to map enums to INT, but in SQLite, INT will come back as an Int64, and, since you can't specify that your enum is castable to long, you will get this error. I am using NHibernate, so my workaround was to create a custom AliasToBean class that handles converting the enum fields to Int32:

public class AliasToBeanWithEnums<T> : IResultTransformer where T : new()
{
    #region IResultTransformer Members

    public IList TransformList(IList collection)
    {
        return collection;
    }

    public object TransformTuple(object[] tuple, string[] aliases)
    {
        var t = new T();
        Type type = typeof (T);
        for (int i = 0; i < aliases.Length; i++)
        {
            string alias = aliases[i];
            PropertyInfo prop = type.GetProperty(alias);
            if (prop.PropertyType.IsEnum && tuple[i] is Int64)
            {
                prop.SetValue(t, Convert.ToInt32(tuple[i]), null);
                continue;
            }

            prop.SetValue(t, tuple[i], null);
        }

        return t;
    }

    #endregion
}

Usage:

public IList<ItemDto> GetItemSummaries()
{
    ISession session = NHibernateSession.Current;

    IQuery query = session.GetNamedQuery("GetItemSummaries")
        .SetResultTransformer(new AliasToBeanWithEnums<ItemDto>());

    return query.List<ItemDto>();
}
0
votes

By default, emums are automapped to strings for SQLite (don't know what happens with SQL Server).

Less efficient storage wise, obviously, but that might be a non-issue unless you have really huge data sets.