Tuesday, April 19, 2011

[General-Dev]– Mapping integer Enums in Fluent NHibernate

For those of you that don’t know, Fluent NHibernate is a great project for anyone that uses NHibernate in their .NET development. Instead of creating Hibernate XML files for your mappings (yuck), you can use a strongly typed, 'fluent’ syntax in C# code.  An example mapping for a class would look something like:

   1: Table("Staff");
   2: Id(x => x.Id).Column("Id").GeneratedBy.Native();
   3: Map(x => x.LastSaved);
   4: Map(x => x.FirstName);
   5: Map(x => x.LastName);
   6: References(x => x.SalaryInfo, "SalaryInfoId");

I recently converted some mapping files of my own over from hibernate XML to Fluent NHibernate and came across one gotcha worth mentioning. In my project, I had some Enums as properties. Say for example EmploySection enum might have EmploySection.Administration, EmploySection.Structural, EmploySection.Civil as options. My database had these mapped as integers previously, and NHibernate would take this mapping and cast the enum as an integer and save it to the database.

By default, Fluent NHIbernate does this differently, it uses a string to save the enum value to the database. This caused some issues as I had existing data which needed to read these fields, so I wanted to tell NHibernate how to do this.

The solution is to add ‘.CustomType(typeof(int))’ to the end of your mapping, for example:

   1: Map(x => x.EmploySection).CustomType(typeof(int));
This fixed the problem for me. Also something to note, is that if you get exceptions in your mappings, take a look deeper into the exception as often a cryptic error may hide a more detailed NHibernate error underneath.

No comments: