In this article I’m going to cover how to install and configure NHibernate and use it in a ASP.NET MVC application. This is the first part of a series of articles which demonstrates how to set up NHibernate for a .Net Application.
+

What is NHibernate?
NHibernate is an Object-Relational Mapper (ORM) for .Net which allows object-oriented models to be mapped to a relational database. As you will see in this article, NHibernate will takes care of most of the tasks related to the persistent layer. You can learn more about NHibernate from the NHibernate Community Site.
You can download the latest version of NHibernate from SourceForge. The code examples of this article are based on NHibernate 2.1.1 (Which is the most current version at the moment of writting this post).
Install NHibernate
Download and unzip the NHibernate in your computer. Thats it, NHibernate installed.
Create the ASP.NET MVC project.
Create a new ASP.NET MVC application and make sure to create a test project.
Add two new Class Library Projects to your solution: Infrastructure and Core (to we can keep everything well organized).
In the Core project, add a reference to the NHibernate assembly.+
The Database
For this example we are going to create a model of Posts and Categories, this is a very simple model that will help us to understand how NHibernate works: one blog post can be in one or more categories, and one category can hold zero or more than zero posts:
We will use SQL Server 2008 Express Edition to create our database, another option is to create our models in Visual Studio and command NHibernate to create the database for us, but for this case we will manually create the database.
Creating the Model
The next step is to create our Model which is an object-oriented representation of our database, we will use the Class Designer of Visual Studio to create it:
Repositories
A repository allows us to create, select, update and delete our objects, a repository is independed of the database. For this tutorial we need to create two repositories: PostRepository and CategoryRepository. Both repositories will implement the following interface:
IRepository.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: namespace Core
7: {
8: public interface IRepository<T>
9: {
10: void Save(T entity);
11: void Update(T entity);
12: void Delete(Guid id);
13: T GetById(Guid id);
14: T GetAll();
15: }
16: }
To create our repositories we first need a helper class to create a NHibernate session to our database:
NHibernateHelper.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using NHibernate.Cfg;
6: using NHibernate;
7:
8: namespace Core.Domain.Repositories
9: {
10: public class NHibernateHelper
11: {
12: private static ISessionFactory _sessionFactory;
13:
14: private static ISessionFactory SessionFactory
15: {
16: get
17: {
18: if (_sessionFactory == null)
19: {
20: var configuration = new Configuration();
21: configuration.Configure();
22: _sessionFactory = configuration.BuildSessionFactory();
23: }
24: return _sessionFactory;
25: }
26: }
27:
28: public static ISession OpenSession()
29: {
30: return SessionFactory.OpenSession();
31: }
32: }
33: }
Next, we create the repositories:
PostRepository.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using Core.Domain.Model;
6: using NHibernate;
7: using NHibernate.Criterion;
8:
9: namespace Core.Domain.Repositories
10: {
11: public class PostRepository: IRepository<Post>
12: {
13: #region IRepository<Post> Members
14:
15: void IRepository<Post>.Save(Post entity)
16: {
17: using (ISession session = NHibernateHelper.OpenSession())
18: {
19: using (ITransaction transaction = session.BeginTransaction())
20: {
21: session.Save(entity);
22: transaction.Commit();
23: }
24: }
25: }
26:
27: void IRepository<Post>.Update(Post entity)
28: {
29: using (ISession session = NHibernateHelper.OpenSession())
30: {
31: using (ITransaction transaction = session.BeginTransaction())
32: {
33: session.Update(entity);
34: transaction.Commit();
35: }
36: }
37: }
38:
39: void IRepository<Post>.Delete(Guid id)
40: {
41: using (ISession session = NHibernateHelper.OpenSession())
42: {
43: using (ITransaction transaction = session.BeginTransaction())
44: {
45: session.Delete(id);
46: transaction.Commit();
47: }
48: }
49: }
50:
51: Post IRepository<Post>.GetById(Guid id)
52: {
53: using (ISession session = NHibernateHelper.OpenSession())
54: return session.CreateCriteria<Post>().Add(Restrictions.Eq("Id", id)).UniqueResult<Post>();
55: }
56:
57: Post IRepository<Post>.GetAll()
58: {
59: throw new NotImplementedException();
60: }
61:
62: #endregion
63: }
64: }
CategoryRepository.cs
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using Core.Domain.Model;
6: using NHibernate;
7: using NHibernate.Criterion;
8:
9: namespace Core.Domain.Repositories
10: {
11: public class CategoryRepository: IRepository<Category>
12: {
13: #region IRepository<Category> Members
14:
15: void IRepository<Category>.Save(Category entity)
16: {
17: using (ISession session = NHibernateHelper.OpenSession())
18: {
19: using (ITransaction transaction = session.BeginTransaction())
20: {
21: session.Save(entity);
22: transaction.Commit();
23: }
24: }
25: }
26:
27: void IRepository<Category>.Update(Category entity)
28: {
29: using (ISession session = NHibernateHelper.OpenSession())
30: {
31: using (ITransaction transaction = session.BeginTransaction())
32: {
33: session.Update(entity);
34: transaction.Commit();
35: }
36: }
37: }
38:
39: void IRepository<Category>.Delete(Guid id)
40: {
41: using (ISession session = NHibernateHelper.OpenSession())
42: {
43: using (ITransaction transaction = session.BeginTransaction())
44: {
45: session.Delete(id);
46: transaction.Commit();
47: }
48: }
49: }
50:
51: Category IRepository<Category>.GetById(Guid id)
52: {
53: using (ISession session = NHibernateHelper.OpenSession())
54: return session.CreateCriteria<Category>().Add(Restrictions.Eq("Id", id)).UniqueResult<Category>();
55: }
56:
57: Category IRepository<Category>.GetAll()
58: {
59: throw new NotImplementedException();
60: }
61:
62: #endregion
63: }
64: }
As you can see, is in the repositories where we put the code to call the NHibernate methods, we do it by creating a Session object first.
The history so far…
Before continuing, lets review what have we done so far:
-
We created a Core project with a reference to the NHibernadte.dll assembly.
-
In the Core project, we created two classes that represent our model: “Post.cs” and “Category.cs”, the post class has collection of categories.
-
We created two repositories to save, update, delete and select objects of our model.
The Mappings
Now its time to do some work in our Infrastructure project where will map our model to our database, in NHibernate we do this with XML files. There is a naming convention that we should follow for the map files: [ClassName].hbm.xml.
We will create two new files: Category.hbm.xml and Post.hbm.xml. The content of each file maps a class to a table, and a propery to a column, you also specify the data types. For the first part of this tutorial we need to create the Category.hbm.xml file:
1: <?xml version="1.0" encoding="utf-8" ?>
2: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3: namespace="Core.Domain.Model"
4: assembly="Core">
5:
6: <class name="Category" table="Categories" dynamic-update="true">
7: <cache usage="read-write"/>
8: <id name="Id" column="Id" type="Guid">
9: <generator class="guid"/>
10: </id>
11: <property name="Name" length="100"/>
12: </class>
13: </hibernate-mapping>
IMPORTANT: Set the build action of each map file to “Embedded Resource”, this way NHibernate can find the correct file in the assembly.
Configure it
We are almost ready, the next step is to set the database connection and some NHibernate parameters. The configuration should be in a “hibernate.cfg.xml” file (Set the build action of this file to “Embbeded Resource”). NHibernate has a special “Lazy-Loading” feature for dynamic proxy systems, and we need to add the following references to the Infrastructure project to support it:
Then create the following XML configuration file:
hibernate.cfg.xml
1: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
2: <session-factory>
3: <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
4: <property name="connection.connection_string">server=.\SQLExpress;database=NHibernate101;Integrated Security=true;</property>
5: <property name="show_sql">true</property>
6: <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
7: <property name="cache.use_query_cache">false</property>
8: <property name="adonet.batch_size">100</property>
9: <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
10: <mapping assembly="Infrastructure" />
11: </session-factory>
12: </hibernate-configuration>
Line # 9: Hibernate uses a lazy loading feature , you can find out more about NHibernate lazy load here.
Test it
Now it is time to test our NHibernate configuration!!, lets add some fields to our “Categories” Table, for this we need to reference to the NHibernate assebmly and copy the hibernate.cfg.xml to the test poject.
Add the following references:
And add the following test method:
1: [TestMethod]
2: [DeploymentItem("hibernate.cfg.xml")]
3: public void CanCreateCategory()
4: {
5: IRepository<Category> repo = new CategoryRepository();
6: Category category = new Category();
7: category.Name = "ASP.NET";
8:
9: repo.Save(category);
10:
11: }
Run the test project and our CanCreateCategory test method should pass the test (hopefully):
Now lets check the database to see the new category just added:
Download source code of PART 1
In the next part of this tutorial we will complete the model and the unit tests, then we will create our ASP.NET MVC application.