Mapping Enum to Int With NHibernate
I am pretty sure this subject has been raised numerous times already, but a quick google didn’t really give that many results, hence this post.
Is there a problem officer?
Some time ago, while still newbie with NHibernate I struggled with the default way Enum properties are mapped to database columns.
The problem with NHibernate is that by default it maps enums as nvarchar columns. In my beginnings with NH this caused me some data type mismatch related exceptions and to some extent minor frustration.
Personally I wanted enum values mapped as integer, my rationale being space requirements and better performance, especially if an index is applied over the column in question. As an example I will be using the minimalist mapping below:
1
|
|
Now, as I metioned earlier, the above does not satisfy my expectations. In order to have the UserType property mapped to an int column I implemented a custom IUserType.
The solution: Custom Value Type
The idea of a custom type is simple. Developers can get NHibernate to persist your property’s value to columns of types not supported by the default persisters. It could even be used to persist a property to multiple columns, somewhat like components
My solution is simpler than that though. Implementation consists of three classes:
- abstract UserType class, extending IUserType interface,
- generic EnumAsInt32 class,
- finally, implementation of the above.
The first class exists to simplify further implementations. The IUserType contains definitions for many more method than are actually required to tackle the issue at hand.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
The EnumAsInt32 class overrides the abstract methods of UserType and requires one generic argument - the type of mapped Enum type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Implementation could end here, but with XML mappings, using generic types is pretty cumbersome. Personally I can never get the syntax right. For that reason it is easier to further extend EnumAsInt32.
1 2 3 4 |
|
Simple as that. Too simple even, but the result is cleaner XML mapping:
1
|
|
Of course the example lack namespaces, but otherwise it’s a fully functional code.
Have fun coding! :)