How to persist an enum using NHibernate

Solution 1:

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:

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:

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:

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:

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
}