Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluent NHibernate - How to map a List<enum>?

I have a class and inside it, a string and a list of enumerators.

public enum SomeEnum
{
    Undefined=0,
    Enum1,
    Enum2,
    Enum3,
    End
}
public class SomeObject
{
    public virtual int ID{get; set;}
    public virtual String Name {get; set;}
    public virtual IList<SomeEnum> EnumList {get; set;}
}

Now, there should be a list of SomeObjects, containing ID and Name. There should be another map like this:

5 2
5 3
3 1
9 3

Meaning, a player with ID 5 has Enum2 and Enum3, another player with ID 3 has Enum1, and a player with ID 9 has Enum3. They say it's possible to map int, float etc. but I don't want to create IList out of my list.

Is there an easy way to make fluent nhibernate do that?

HasMany(x => x.EnumList )
    .Cascade.All()
    .Table("ObjectEnumTable");

This mapping file throws an exception and says "Association references unmapped class: SomeEnum".

Thanks in advance.

like image 951
holgac Avatar asked Jul 13 '11 08:07

holgac


2 Answers

You're better off storing your List of enum values as a straight Flags enum value, but if you absolutely must have a list of enums (you need support for duplicates or legacy database), then your mapping shoud look like this:

HasMany(x => x.EnumList )
    .Cascade.All()
    .Table("ObjectEnumTable")
    .Element("EnumValueColumn");

The key is the .Element() method which you must have for any non-entity HasMany relationship, including strings, ints, etc. This will give you the ID column referencing your parent entity, and an EnumValueColumn column with your enum value for each item.

like image 70
StarKat99 Avatar answered Oct 06 '22 05:10

StarKat99


The problem is not that you try to persist an Enum although it helps if you specify a base type. The problem is that you try to store a list (this becomes a one to many association in NHibernate). The items in the list have to be objects so that NHibernate can map them to a table. Is it an option to create an object with just an Id and your Enum value? This will allow NHibernate to persist it. Or if you are afraid of the performance hit, create getter and setter logic that can store your complete list as a string.

public class SomeObject
{
    public virtual int Id { get; set; }
    public virtual String Name { get; set; }
    public virtual IList<SomeEnumClass> EnumList { get { return enumList; } set     { enumList = value; } }
    private IList<SomeEnumClass> enumList = new List<SomeEnumClass>();
}

public enum SomeEnum : int
{
    Undefined = 0,
    Enum1,
    Enum2,
    Enum3,
    End
}


public class SomeEnumClass
{
    public virtual int Id { get; set; }
    public virtual SomeEnum Value {get; set;}
}

You may also look at: Map List<Int32> using Fluent Nhibernate

like image 40
k.c. Avatar answered Oct 06 '22 04:10

k.c.