How to persist an enum using NHibernate

NhibernateEnumsPersistenceForeign Keys

Nhibernate Problem Overview


Is there a way to persist an enum to the DB using NHibernate? That is have a table of both the code and the name of each value in the enum.

I want to keep the enum without an entity, but still have a foreign key (the int representation of the enum) from all other referencing entities to the enum's table.

Nhibernate Solutions


Solution 1 - Nhibernate

Why are you guys over complicating this? It is really simple.

The mapping looks like this:

<property name="OrganizationType"></property>

The model property looks like this:

public virtual OrganizationTypes OrganizationType { get; set; }

The Enum looks like this:

public enum OrganizationTypes
{
    NonProfit = 1,
    ForProfit = 2
}

NHibernate will automatically figure it all out. Why type more than you need????

Solution 2 - Nhibernate

You can use the enum type directly: http://web.archive.org/web/20100225131716/http://graysmatter.codivation.com/post/Justice-Grays-NHibernate-War-Stories-Dont-Use-Int-If-You-Mean-Enum.aspx. If your underlying type is a string, it should use the string representation, if it is numeric, it will just use the numeric representation.

But your question wording sounds like you're looking for something different, not quite an enum. It seems that you want a lookup table without creating a separate entity class. I don't think this can be done without creating a separate entity class though.

Solution 3 - Nhibernate

An easy but not so beautiful solution:

Create an integer field with and set the mapping in the mapping file to the field. Create a public property that uses the integer field.

private int myField;
public virtual MyEnum MyProperty
{
   get { return (MyEnum)myField; }
   set { myField = value; }
}

Solution 4 - Nhibernate

I am using NHibernate 3.2, and this works great:

type="NHibernate.Type.EnumStringType`1[[enum_full_type_name, enum_assembly]], NHibernate"

Not sure when the generic EnumStringType got added, though.

Solution 5 - Nhibernate

Try using a stategy pattern. Uou can then put logic into your inner classes. I use this quite alot espically when there is logic that should be contained in the "enum". For example the code below has the abstract IsReadyForSubmission() which is then implemented in each of the nested subclasses (only one shown). HTH

[Serializable]
public abstract partial class TimesheetStatus : IHasIdentity<int>
{
        public static readonly TimesheetStatus NotEntered = new NotEnteredTimesheetStatus();
        public static readonly TimesheetStatus Draft = new DraftTimesheetStatus();
        public static readonly TimesheetStatus Submitted = new SubmittedTimesheetStatus();
        //etc

        public abstract int Id { get; protected set; }
        public abstract string Description { get; protected set; }
        public abstract bool IsReadyForSubmission();

        protected class NotEnteredTimesheetStatus: TimesheetStatus
        {
            private const string DESCRIPTION = "NotEntered";
            private const int ID = 0;
            public override int Id
            {
                get { return ID; }
                protected set { if (value != ID)throw new InvalidOperationException("ID for NotEnteredTimesheetStatus must be " + ID); }
            }

             public override string Description
            {
                get { return DESCRIPTION; }
                protected set { if (value != DESCRIPTION)throw new InvalidOperationException("The description for NotEnteredTimesheetStatus must be " + DESCRIPTION); }
            }
            public override bool IsReadyForSubmission()
            {
                return false;
            }

        }
        //etc
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMeidan AlonView Question on Stackoverflow
Solution 1 - NhibernateEmadView Answer on Stackoverflow
Solution 2 - NhibernateGaro YeriazarianView Answer on Stackoverflow
Solution 3 - NhibernatePacoView Answer on Stackoverflow
Solution 4 - NhibernateJamieView Answer on Stackoverflow
Solution 5 - NhibernateRhysCView Answer on Stackoverflow