Click here to Skip to main content
12,831,317 members (46,626 online)
Click here to Skip to main content
Add your own
alternative version


39 bookmarked
Posted 6 May 2012

Simplify Database Operations with Generic Fluent NHibernate

, , 30 May 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
This article describes database communication using a generic Fluent NHibernate implementation.


Developing a feature-rich database library can be difficult for large enterprise applications because of multiple requirements. These instructions have been fully tested using the following technologies:

  • .NET Framework 4.0
  • ASP.NET MVC 3 (with Razor)
  • Fluent NHibernate 1.3 and NHibernate 3.2.
  • Microsoft SQL Server 2008 R2 and SQL CE databases.

This article offers up a complete generic implementation of Fluent NHibernate but does not go into advanced detail on some of the additional features that it can provide. Visit Fluent NHibernate's website to get additional information on implementing it. 


NHibernate is an object-relational mapping software package for the .NET platform that provides code for mapping object-oriented classes to relational database tables. It abstracts the SQL required for interaction with a database so that the developer can focus on the business requirements of the application. Fluent NHibernate provides XML-free mappings for NHibernate, allowing for the same functionality with a cleaner interface using a standard, generic implementation. Fluent NHibernate can be downloaded directly into your project using NuGet, which will check for dependencies then download and reference the files necessary to get started. The command below can be executed in the Package Manager Console to retrieve Fluent NHibernate with its dependencies.  

Install-Package FluentNHibernate –Project Your.Project.Name

Step 1: Create Session Manager

The Fluent NHibernate Session Manager is used to administer the session that the developer will use to connect to the database. The required functionality of the manager is to hold references to the session, implement the unit of work design pattern, manage transactions to the database, and handle cleanup and disposal of the session when necessary. The interface for the Session Manager is shown below, containing the Session that will be used, rollback and commit functions, and a cleanup function.

public interface IFNHSessionManager
    ISession Session { get; }

    void CleanUp();
    void Rollback();
    void Commit();

The Session Manager needs several properties for it to function. It needs to hold a reference to the session factory, the session, and the transaction. The transaction can be private because we are exposing the Rollback and Commit functions later in this class which allow the implementation of the unit of work design pattern. The code that has been added to the Session property is to bind it to the HttpContext. This way, the cleanup and disposal functions can retrieve the bound Session to complete requests.

private readonly ISessionFactory _sessionFactory;

public ISessionFactory SessionFactory
    get { return _sessionFactory; }

public ISession Session
        if (!ManagedWebSessionContext.HasBind(HttpContext.Current, SessionFactory))
            ManagedWebSessionContext.Bind(HttpContext.Current, SessionFactory.OpenSession());
        return _sessionFactory.GetCurrentSession();

private readonly ITransaction _transaction;

Next, we need a constructor for the Session Manager that wires everything up. The configuration code can be implemented in a separate class (usually called FNHibernateHelper) but for simplicity, I have included it in the constructor. Another important step when using Fluent NHibernate with an ASP.NET web application is that when you bind the Session to the HttpContext, you also include a line that binds the cleanup function to the EndRequest event.

public FNHSessionManager(string dbConfigKey, DatabaseType dbType)
    switch (dbType)
        case DatabaseType.MsSql:
            _sessionFactory = Fluently.Configure()
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<T>())
        case DatabaseType.MsSqlCe:
            _sessionFactory = Fluently.Configure()
                        .ConnectionString(c => c.FromConnectionStringWithKey(dbConfigKey))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<T>())

    if (HttpContext.Current != null && HttpContext.Current.ApplicationInstance != null)
        HttpContext.Current.ApplicationInstance.EndRequest += (sender, args) => CleanUp();

    _transaction = Session.BeginTransaction();

The Rollback and Commit functions are the implementation of the unit of work design pattern. As shown below, it allows the developer to run a procedure (Create, Update, Delete, and Retrieve being the common ones) as a single transaction that can be rolled up into one request to the database.

public void Rollback()
    if (_transaction.IsActive)

public void Commit()
    if (_transaction.IsActive)

Finally, the manager implements the cleanup/dispose functions that complete a transaction at the end of the request. The dispose function implements the Cleanup function and disposes of the current session. This function should only be called at the end event of the application, not at the end of the request. There are two cleanup functions, one generic that allows for any context to which the Session could be bound, but the other specifies the context as the current HttpContext. This would be the more common usage of the Cleanup function.

/// <span class="code-SummaryComment"><summary>

This concludes the code for the NHibernate Session Manager which implements a class to manage the session and unit of work. This code can be found in the files named IFNHSessionManager.cs and FNHSessionManager.cs.

Step 2: Create Generic Repository

The FNHRepository is used to administer database operations (i.e. Create, Retrieve, Update, and Delete). It contains a reference to the previously (Step 1) developed FNHSessionManager so that it has access to a Session that can execute the specified operation on the database. The interface shown below shows the main operations that NHibernate will provide you when communicating with the database. There are several other features of NHibernate that can be leveraged here, including functionality that leverages LINQ (not discussed in this article). Be sure to notice that the implementation is generic so we don’t have to implement the repository for every object that we create.

public interface IFNHRepository<T>
    void Create(T objectToAdd);
    T RetrieveById(int id);
    void Update(T objectToUpdate);
    void Delete(T objectToDelete);

Below is the only property contained in the FNHRepository – a reference to the Session Manager developed in Step 1. This property is read only because it can be set in the constructor and for the remainder of the lifetime of this object, it should stay the same.

public readonly IFNHSessionManager _sessionManager;

Next, we need a constructor to create the Repository and provide a reference to the Session Manager object that is created using the database type and connection string that corresponds to the action being requested.

public FNHRepository(IFNHSessionManager sessionManager)
    _sessionManager = sessionManager;

Finally, the Repository requires implementation to the NHibernate API for communication with the database. The basic functionality implemented here includes CRUD operations (Create, Retrieve, Update, and Delete).

/// <span class="code-SummaryComment"><summary>

This concludes the implementation of the NHibernate Repository which allows for operations that communicate with the database. The code contained in this step can be found in IFNHRepository.cs and FNHRepository.cs.

Step 3: Create Objects

Any business objects that are required for the application to run must be created next so that there is a domain with which to work. These objects are the Models that will be used in the web application so there may be a need to further define the objects with data attributes and other functionality. For this example, I have created three classes: Employee, Role, and Task.


public class Employee

    public virtual int Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string Position { get; set; }
    public virtual ICollection<Role> EmployeeRoles { get; set; }

    public Employee()
        EmployeeRoles = new HashSet<Role>();


public class Role

    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Employee> Employees { get; set; }
    public virtual ICollection<Task> Tasks { get; set; }

    public Role()
        Employees = new HashSet<Employee>();
        Tasks = new HashSet<Task>();


public class Task

    public virtual int Id { get; set; }
    public virtual string TaskName { get; set; }
    public virtual string Description { get; set; }

    public Task()

One thing to note here is that every property that you want to map needs to be set to virtual. Secondly, whenever a collection is used, the property should be defined using the interface and initialized as the concrete class in the constructor.

Step 4: Create Object Mappings

The final step before implementation of the user interface is to define the object mappings so that NHibernate knows what to do with the properties.


public class EmployeeMap : ClassMap<Employee>

    public EmployeeMap()

        Id(x => x.Id).Column("EmployeeId");
        Map(x => x.FirstName);
        Map(x => x.LastName);
        Map(x => x.Position);
        HasManyToMany<Role>(x => x.EmployeeRoles).Table("xrEmployeeRoles")


public class RoleMap : ClassMap<Role>

    public RoleMap()

        Id(x => x.Id).Column("RoleId");
        Map(x => x.Name);
        HasManyToMany<Employee>(x => x.Employees).Table("xrEmployeeRoles")
        HasManyToMany<Task>(x => x.Tasks).Table("xrRoleTasks")


public class TaskMap : ClassMap<Task>

    public TaskMap()

        Id(x => x.Id).Column("TaskId");
        Map(x => x.TaskName);
        Map(x => x.Description);

There are several things to note about the mappings. I have specified the Schema and Table explicitly in the mapping to mitigate any confusion about where the data is coming from. Next, my database entities have a different column name as the identities implemented in my C# objects. Because of this, the column name must be specified as a part of the mapping. Since there are two cross reference tables, this has created a many-to-many relationship between these objects. The mapping must reflect the table with which to reference and the parent and child keys in order to properly execute. The many-to-many relationship ends up as a set, so that must be specified in the mapping as well.

Step 5: Utilize Fluent NHibernate

Once the class library above has been implemented, the only thing left is to use it to develop the user interface. Enter a record into the Employee table and replace the 1 in the call to RetrieveById to get your record.


FNHSessionManager<Employee> sessionManager = new FNHSessionManager<Employee>(_connString, FNHSessionManager<Employee>.DatabaseType.MsSql);
FNHRepository<Employee> repository = new FNHRepository<Employee>(sessionManager);

Employee emp = repository.RetrieveById(1);

The code sample shown above creates an instance of the SessionManager and passes that to the Repository. Once the Repository has been created, it can be used to interact with the database.

Points of Interest

Fluent NHibernate makes getting data from the database incredibly easy. Creating a web project with a generic database CRUD utility with Fluent NHibernate is as simple as this article documents and makes development fast and easy. If there is interest in a test solution for the code presented, I would be happy to write a follow up article.


No changes as of yet.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Authors

Kieran Maltz
Software Developer (Senior) Cayen Systems
United States United States
I am a software engineer based in Milwaukee, Wisconsin. I have been developing software as a hobby since high school and professionally since 2006. I am on a never-ending quest for proper programming principles and clean coding techniques.

Cayen Systems
Cayen Systems
United States United States
Cayen Systems develops online data management software for non-profit and education organizations with a team of experienced and dedicated individuals located in Milwaukee, Wisconsin. We provide the most comprehensive software solutions for information management, tracking and data reporting available today. Specializing in developing easy to use and efficient solutions, we consistently help our clients increase their productivity and reduce the costs of program management.
Group type: Organisation

22 members

You may also be interested in...


Comments and Discussions

GeneralNhibernate queries Pin
J A Srikanth15-Sep-14 11:13
memberJ A Srikanth15-Sep-14 11:13 
QuestionGreat Article Pin
Member 822303931-Jul-13 23:42
memberMember 822303931-Jul-13 23:42 
AnswerRe: Great Article Pin
Kieran Maltz2-Aug-13 7:06
memberKieran Maltz2-Aug-13 7:06 
BugMapping - Task to Role Pin
SilvioDelgado12-Nov-12 11:45
memberSilvioDelgado12-Nov-12 11:45 
QuestionIs Any Performace Issue? Pin
vinoth.arunraj8612-Oct-12 0:57
groupvinoth.arunraj8612-Oct-12 0:57 
AnswerRe: Is Any Performace Issue? Pin
youngnacs7-Nov-14 4:23
memberyoungnacs7-Nov-14 4:23 
GeneralRe: Is Any Performace Issue? Pin
Kieran Maltz7-Nov-14 5:39
memberKieran Maltz7-Nov-14 5:39 
QuestionWhat if I'm not using ASP.NET? Pin
Member 765453419-Jul-12 0:34
memberMember 765453419-Jul-12 0:34 
AnswerRe: What if I'm not using ASP.NET? Pin
Kieran Maltz19-Jul-12 4:41
memberKieran Maltz19-Jul-12 4:41 
There are several ways that you could modify this code to work in a non-ASP.NET environment.

Essentially, you would have to remove all of the references to the web contexts and instead call the CleanUp and/or Dispose functions from your repository or from a delegate after your request to the database has been completed, depending on the action you are trying to complete.
GeneralRe: What if I'm not using ASP.NET? Pin
Member 765453419-Jul-12 22:55
memberMember 765453419-Jul-12 22:55 
GeneralRe: What if I'm not using ASP.NET? Pin
Kieran Maltz20-Jul-12 3:46
memberKieran Maltz20-Jul-12 3:46 
QuestionGreat Job Pin
fatespinnerx2-Jul-12 17:29
memberfatespinnerx2-Jul-12 17:29 
AnswerRe: Great Job Pin
Kieran Maltz3-Jul-12 4:14
memberKieran Maltz3-Jul-12 4:14 
GeneralIt's great Pin
Moch Lutfi18-May-12 17:56
memberMoch Lutfi18-May-12 17:56 
Questionvery good Pin
vlado0512-May-12 12:23
membervlado0512-May-12 12:23 
AnswerRe: very good Pin
Kieran Maltz13-May-12 5:56
memberKieran Maltz13-May-12 5:56 
GeneralMy vote of 5 Pin
Ambalavanar Thirugnanam8-May-12 4:21
memberAmbalavanar Thirugnanam8-May-12 4:21 
GeneralRe: My vote of 5 Pin
Kieran Maltz10-May-12 5:13
memberKieran Maltz10-May-12 5:13 
GeneralVery Clear and Informative Pin
rcarlson-cayen7-May-12 9:25
grouprcarlson-cayen7-May-12 9:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170326.1 | Last Updated 30 May 2012
Article Copyright 2012 by Kieran Maltz, Cayen Systems
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid