maxs87
maxs87

Reputation: 2284

Fluent Nhibernate Enum Mapping

I have some problem with enum mapping in fluent NHibernate. I know this question has been asked many times but I couldn't find any solution that worked for me. I'm newbie in NHibernate and it looks like I may have missed something simple and stupid. Here is my code.

public class DBPublication
{
    public virtual int pub_id { get; set; }
    public virtual PublicationStatuses status { get; set; }
    ...
}

public enum PublicationStatuses 
{
    on_moderation,
    active,
    ...
}


public class DBPublicationMap : ClassMap<DBPublication>
{
    public DBPublicationMap()
    {
        Table("content.publications");
        Id(x => x.pub_id).GeneratedBy.Sequence("content.pub_sq");           
        Map(x => x.status);
        ...
    }
}

postgres enum type

CREATE TYPE content.enum_publication_status AS ENUM('on_moderation', 'active', ...);

but when I try to save, postgres throws this

column "status" is of type content.enum_publication_status but expression is of type text

any suggestion?

Upvotes: 5

Views: 10921

Answers (3)

Mike Christensen
Mike Christensen

Reputation: 91638

Simply add this class to your project:

public class PgEnumMapper<T> : NHibernate.Type.EnumStringType<T>
{
   public override NHibernate.SqlTypes.SqlType SqlType
   {
      get { return new NHibernate.SqlTypes.SqlType(System.Data.DbType.Object); }
   }
}

Then, you can use:

Map(x => x.status).CustomType<PgEnumMapper<PublicationStatuses>>();

Upvotes: 0

Sly
Sly

Reputation: 15227

Here is a working sample of configuring nhibernate to store enum field.

public class Entity
{
    public virtual int id { get; set; }

    public virtual SomeEnum EnumField { get; set; }
}

public enum SomeEnum
{
    Value1,
    Value2
}

class EntityMap : ClassMap<Entity>
{
    public EntityMap()
    {
        Id(x => x.id).GeneratedBy.Native();
        Map(x => x.EnumField);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var factory = Fluently.Configure().Mappings(x => x.FluentMappings.AddFromAssemblyOf<Entity>())
                                .ExposeConfiguration(config => new SchemaExport(config).Create(false, true))
                                .Database(MsSqlConfiguration.MsSql2008.ConnectionString("Data Source=.;Initial Catalog=nhtest;Integrated Security=True"))
                                .BuildSessionFactory();
        using (var session = factory.OpenSession())
        {
            using (var transaction = session.BeginTransaction())
            {
                var entity = new Entity();
                entity.EnumField = SomeEnum.Value2;
                session.Save(entity);
                transaction.Commit();
            }
        }

    }
}

In such case it is stored as strings in data base. If you want it be saved as integers, you need to change mapping for Enum field property to the following:

Map(x => x.EnumField).CustomType<int>();

Upvotes: 7

Alex
Alex

Reputation: 84

Why are you creating enum types in progres? isn't this a maintenance-nightmare? What does your configuration look like? Have you already tried using the conventions discribed here? Looks like a simple casting error, so please consider using CustomType() / CustomSQLType() inside your mapping.

Upvotes: 1

Related Questions