Continuing where we left off from part 1, we had created a class library called DomainModel and created four classes to act as data transfer objects.
In this part we’ll create our first NHibernate mapping for the Product entity.
Lets revisit what our Product class looks like first.
We have three properties which we want to map to our columns in the database. NHibernate does this using XML files.
Quick tip: Make sure you’ve brought the nhibernate-configuration.xsd and nhibernate-mapping.xsd files into your solution. They are in the NHibernate redistributable you would have downloaded from nhforge. This will give you IntelliSense when editing the NHibernate xml mapping and configuration files.
Create the Mapping File
Create a new folder in your DomainModel project called Mappings and inside it create an xml file called Product.hbm.xml.
For NHibernate to read your configuration at run-time, this file needs to be made an embedded resource. Select the file in your solution explorer, then go to properties and set Build Action to Embedded Resource.
NHibernate’s convention is to name your mapping with a .hbm.xml extension. This can be overridden if needed, but would defeat the objective of convention over configuration ;)
Build the Mapping
For NHibernate to map your entity to the database, it needs to know
- The assembly and namespace of the class being mapped.
- The name of the class being mapped.
- The name of the table the class is being mapped to.
- What the unique identifier of the class is.
- What column each property must be mapped to.
Open your Product.hbm.xml file and add your root element.
The hibernate-mapping element defines three attributes here.
- The xmlns attribute sets your namespace and lets Visual Studio give you IntelliSense
- The assembly attribute tells NHibernate what the default assembly is for types that don’t have fully qualified type names.
- The namespace attribute tells NHibernate which namespace to look in for types that don’t have fully qualified type names.
The next thing NHibernate needs to know is the detail about the class being mapped, so add a class element.
Based on the assembly and namespace in the hibernate-mapping element, this tells NHibernate to map the DomainModel.Product class from the DomainModel assembly to the table called Product. Note that we could have omitted the table attribute here and NHibernate would have used the class name as the table name. However, I find using the table attribute makes the mapping file easier to understand when reading it.
NHibernate needs to know two more things about our entity now. It needs a unique identifier for the entity. This is done with the Id element under the class element.
From this, NHibernate will use the Id column on the table as the unique identifier for each record and knows that the database will generate new identity values for new records. Note that no property on our class maps to the Id column and therefore we need to explicitly tell it that it is of type System.Int32.
The last thing NHibernate needs to know about our Product is the properties that it must map. These are added using the property tag after the id tag.
After adding these three lines, here’s our complete mapping file.
And that’s it! We could now open a new NHibernate.ISession and get a list of all of our products from the database.
In the next part of this series we’ll map our Order and OrderDetail classes and handle the one-to-many and many-to-one elements in the NHibernate configuration. We’ll also look at the different types of collections NHibernate uses and when each is appropriate.