I described earlier how you could use your own enum types in the NHibernate Designer. But NHibernate doesn’t limit you to built-in and enum types. You can also create your own mappings, for when you’ve got a custom type or you need it to map to the database in a custom way. For example, suppose you’re dealing with a legacy database column which represents a boolean value by the strings HUZZAH and OH NOES. (Not only legacy, but clearly very silly.) Obviously, you’d like to represent this in your object model as a boolean property rather than a string. In the NHibernate runtime, you can handle this by implementing the IUserType interface to tell NHibernate how to translate between the database and CLR representations. But how do you hook it up in the designer?
As with enums, the answer is that you can define a custom data type. Then, rather than specifying the property as being a Boolean, you specify it as being the custom data type. The designer will still generate the .NET property as type Boolean, but will add your IUserType to the mapping and won’t try to change the column to a Boolean during database synchronisation.
Let’s see it in action.
First, we go to the NHibernate Model Explorer (View > Other Windows > NHibernate Model), right-click the model and choose Add New User Mapped Type:
We now need to tell the designer what CLR type it should use for properties of this kind, and how to map them to the database. We also need to give it a name for when it appears in the Data Type drop-down:
The crucial things here are the CLR Type Name and the Mapping Type. The CLR Type Name is the .NET type that you want to be emitted for properties of this type. The Mapping Type is the name of the IUserType implementation that performs the mapping, and must be an assembly-qualified name — i.e. full_class_name,assembly_name.
If you want to use schema roundtripping, you can also enter the backing type for database columns of this type. This doesn’t affect NHibernate at runtime — it just ensures that you get the right kind of column if you use the designer to create your database schema.
With this in place, we can now use the user mapped type just as we can use any other data type:
And the designer will generate the property as a System.Boolean and a mapping using the specified IUserType.