An improperly mapped enumeration can lead to unnecessary updates. In this recipe, I'll show you how to map an enumeration property to a string field.
MappingEnums
.AccountTypes
enumeration:public enum AccountTypes { Consumer, Business, Corporate, NonProfit }
public class Account { public virtual Guid Id { get; set; } public virtual AccountTypes AcctType { get; set; } public virtual string Number { get; set; } public virtual string Name { get; set; } }
<class name="Account"> <id name="Id"> <generator class="guid.comb" /> </id> <natural-id> <property name="Number" not-null="true" /> </natural-id> <property name="Name" not-null="true" /> <property name="AcctType" not-null="true" /> </class>
property
element for AcctType
, add a type
attribute with the following value:NHibernate.Type.EnumStringType`1[[MappingEnums.AccountTypes, MappingEnums]], NHibernate
By default, NHibernate will map an enumeration to a numeric field based on the enumeration's underlying type, typically an int
. For example, if we set AcctType
to AccountTypes.Corporate
, the AcctType
database field would hold the integer 2. This has one significant drawback. An integer value by itself doesn't describe the business meaning of the data.
One solution is to create a lookup table containing each enumeration value alongside a description, but this must be maintained in perfect sync with the application code because otherwise it can lead to serious versioning issues. Simply rearranging the order of the enumeration in code from one release to the next can have disastrous effects.
Another solution, the one shown here, is to store the name of the enumeration value in a string field. For example, if we set AcctType
to AccountTypes.Corporate
, the AcctType
database field would hold the string value Corporate
.
By specifying a type
attribute for AcctType
, we tell NHibernate to use a custom class for conversion between .NET types and the database. NHibernate includes EnumStringType<T>
to override the conversion of enumeration values to database values so that the string name is stored, not the numeric value.
The type
value NHibernate.Type.EnumStringType`1[[MappingEnums.AccountTypes, MappingEnums]], NHibernate
is the assembly qualified name for NHibernate.Type.EnumStringType<AccountType>
.