NHibernate is a mature, open source object-relational mapper for the .NET framework. It is a quite popular framework for abstracting and handling the persistence layer.

In the following post I will describe the procedure of configuring and setting up NHibernate in MVC Application.

First of all we need to create Empty MVC Application.

Via Nuget Gallery we are going to install NHibernate (Right click on the project -> Manage Nuget Packages -> Browse -> NHibernate -> Install)

nugetnhibernateinstall.png

The following reference is added to the project.

nhibernateDLL.png

Next we create class called NHibernateInitializator.cs. We put the following code in the newly created class.

public static class NHibernateInitializator
{
    private static ISessionFactory _factory;
    private static ISession _session;
    private static object _lock = new object();

    public static ISessionFactory InitializeConfiguration()
    {
        if (_factory == null)
        {
             var cfg = new NHibernate.Cfg.Configuration();

             cfg.AddAssembly(Assembly.GetExecutingAssembly());

             _factory = cfg.BuildSessionFactory();
         }

          return _factory;
      }

      public static ISession OpenSession()
      {
           return Factory.OpenSession();
      }

      public static void CreateSession()
      {
          CurrentSessionContext.Bind(OpenSession());
      }

      public static void CloseSession()
      {
           if (CurrentSessionContext.HasBind(Factory))
           {
               CurrentSessionContext.Unbind(Factory).Dispose();
           }
      }

      public static ISession GetCurrentSession()
      {
           if (!CurrentSessionContext.HasBind(Factory))
           {
              CurrentSessionContext.Bind(OpenSession());
           }
           return Factory.GetCurrentSession();
       }

       public static ISessionFactory Factory
       {
            get
            {
                 lock (_lock)
                 {
                      if (_factory == null)
                      {
                           InitializeConfiguration();
                      }
                      return _factory;
                  }
             }
         }

         public static ISession Session
         {
             get
             {
                 if (_session == null)
                 {
                      _session = GetCurrentSession();
                 }
                 return _session;
             }
          }
 }

This class has methods that manipulate the Session and initialize the entire factory.

Next we need to call the specific methods from this class in the Global.asax file.

First we add the following code in the Application_Start() method.

NHibernateInitializator.InitializeConfiguration();

Then we add the following code:

protected void Application_BeginRequest(object sender, EventArgs e)
{
    NHibernateInitializator.CreateSession();
}

protected void Application_EndRequest(object sender, EventArgs e)
{
    NHibernateInitializator.CloseSession();
}

Next we configure NHibernate in Web.config file of the MVC Application.

 <configSections>
 <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
 <section name="nhibernate.mapping" type="System.Configuration.NameValueSectionHandler" />
 </configSections>
 <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
 <session-factory>
 <!-- Sql Connection -->
 <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
 <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
 <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
 <property name="connection.connection_string">Data Source=.;Database=TestDB;User ID=sa;Password=P@ssw0rd;Connect Timeout=10;</property>

 <!-- Properties -->
 <property name="default_schema">dbo</property>
 <property name="cache.use_minimal_puts">true</property>
 <property name="current_session_context_class">web</property>
 <property name="show_sql">true</property>
 <property name="prepare_sql">false</property>
 <property name="generate_statistics">false</property>
 <property name="query.substitutions">true 1, false 0</property>
 <property name="adonet.batch_size">20</property>

 <!-- HBM Mapping Files -->
 <mapping assembly="NHibernateConfiguration.Data" />
 </session-factory>
 </hibernate-configuration>

In the database we have 1 table named Users with the following columns:

USE [TestDB]
GO

/****** Object: Table [dbo].[Users] Script Date: 11/2/2016 4:19:04 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Users](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [FirstName] [nvarchar](50) NOT NULL,
 [LastName] [nvarchar](50) NOT NULL,
 [Email] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

We create the coresponding hbm file named User.hbm.xml and set it up as Embedded Resource.

 <?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="NHibernateConfiguration" namespace="NHibernateConfiguration.Domain" xmlns="urn:nhibernate-mapping-2.2">
 <class name="User" table="Users" lazy="true" >
 <id name="Id" column="Id">
 <generator class="identity" />
 </id>
 <property name="FirstName">
 <column name="FirstName" sql-type="nvarchar" not-null="true" />
 </property>
 <property name="LastName">
 <column name="LastName" sql-type="nvarchar" not-null="true" />
 </property>
 <property name="Email">
 <column name="Email" sql-type="nvarchar" not-null="true" />
 </property>
 </class>
</hibernate-mapping>

The coresponding domain class is named User.cs.

public class User
{
    public virtual int Id { get; set; }

    public virtual string FirstName { get; set; }

    public virtual string LastName { get; set; }

    public virtual string Email { get; set; }
}

The final step is to test if everything is configured correctly.

public class HomeController : Controller
{
    private ISession _session;

    public HomeController()
    {
        _session = NHibernateInitializator.GetCurrentSession();
    }

    // GET: Home
    public ActionResult Index()
    {
        using (var tx = _session.BeginTransaction())
        {
           var user = new User();

           user.Id = 1;
           user.FirstName = "Martin";
           user.LastName = "Kostovski";
           user.Email = "test@test.com";

           _session.Save(user);

           tx.Commit();
         }

         return View();
     }
 }

All the best,

Martin

Advertisements