Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / .NET

NHibernate with MVC3 Razor Engine

4.00/5 (3 votes)
13 Aug 2013CPOL5 min read 30.2K   1.4K  
Here we are going to create NHibernate architecture with MVC3 Razor engine.

Introduction 

Here we are going to create NHibernate architecture for MVC3 with razor engine. Before start this tutorial you should familiar about MVC3, Razor, and NHibernate. NHibernate uses Object Relational Mapping (ORM). You can find basic information from another tutorial from same site. Here we are going to create one basic and simple application using NHibernate architecture with MVC3 razor engine.

Background

The basic information you will get from here:

Using the code

Here we go step by step. 

First , Start your visual studio => Select new project with MVC3 application .Make sure you have select Razor engine. You will have sample site in MVC3 with Razor. Install Nhibernate package using NuGet Package.So you will get DLL for NHibernate.dll and its dependency Iesi.Collection.dll. This step is Optional for you ,because you can also find dll from attachment source but if it doesn't work for you then you should create it by own via installing a package.Then run the attached database script. You will have database named NHibernate101.

Now add two class libraries named Core and Infrasturcture respectively. Give the reference of NHibernate.dll and its dependency Iesi.Collection.dll to Core library (you'll find it in your package folder if you had installed it using NuGet package) and create the interface IRespository.cs (can get from attached source )

Code block:

C#
namespace Core
{
    public interface IRepository<T>
    {
        void Save(T entity);
        void Update(T entity);
        void Delete(T entiy);
        T GetById(Guid id);
        IList<T> GetAll();
    }
}

Now create folder Domain in Core library, and create Model and Repositories under the Domain folder. In the Model folder we will create the entity class and ,in the Repositories folder we will create methods for CRUD. You have to do one extra task is that, have to add NHibernateHelper.cs in Repositories folder. You will get it from source code. 

Create the entity class Category.cs in Model folder

C#
namespace Core.Domain.Model
{
    public class Category
    {
        public virtual Guid Id { get; set; }

        public virtual string Name { get; set; }
    }
}

Create CategoryRepository.cs in the Repositories folder. It is implements IRepository interface, which is we have created before. Here we implements IRepository with Category entity. And we also override the every method which we defined in interface. This class contains methods for CRUD (create, retrieve, update and delete.) a category.

C#
namespace Core.Domain.Repositories
{
    public class CategoryRepository:IRepository<Category>
    {
        #region IRepository<Category> Members

        void IRepository<Category>.Save(Category entity)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(entity);
                    transaction.Commit();
                }
            }
        }

        void IRepository<Category>.Update(Category entity)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(entity);
                    transaction.Commit();
                }
            }
        }

        void IRepository<Category>.Delete(Category entity)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(entity);
                    transaction.Commit();
                }
            }
        }

        Category IRepository<Category>.GetById(Guid id)
        {
            using (ISession session = NHibernateHelper.OpenSession())
                return session.CreateCriteria<Category>().Add(
                  Restrictions.Eq("Id", id)).UniqueResult<Category>();
        }

        IList<Category> IRepository<Category>.GetAll()
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                ICriteria criteria = session.CreateCriteria(typeof(Category));
                return criteria.List<Category>();
            }
        }

        #endregion
    }
}

Now Core Library is ready for use. So we move on our another library Infrastructure. Here we are mapping the objects.

In first step create one xml file for database configuration. Make sure it's extension ends with .cfg.xml (here hibernate.cfg.xml). add this code in it.

XML
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">
    PASTE YOUR CONNECTIONSTRING HERE
    </property>
    <property name="show_sql">true</property>
    <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
    <property name="cache.use_query_cache">false</property>
    <property name="adonet.batch_size">100</property>
    <mapping assembly="Infrasturcture" />
  </session-factory>
</hibernate-configuration>

Now go to the properties of this file and set Copy To Output Directory to Copy Always.

Now we create the xml file for object mapping. For these create the folder named DataAccess. Then create the folder Mappings in it. Now here we are working on Category table so we'll create the object mapping file for same. So create the Category.hbm.xml file in Mappings folder. This is a simple XML file but make it has .hbm.xml extension. The code block for Category.hbm.xml is:

XML
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="Core.Domain.Model"
                   assembly="Core">

  <class name="Category" table="Categories" dynamic-update="true">
    <cache usage="read-write"/>
    <id name="Id" column="Id" type="Guid">
      <generator class="guid"/>
    </id>
    <property name="Name" length="100"/>
  </class>
</hibernate-mapping>

Here name space is Core.Domain.Model, where we have been created Entity class. In the mapping file we have to mention column name (with respective data type and length) which are existed in Category table in database. Now select the properties of Category.hbm.xml and select Build Action as Embedded Resource. Now our infrastructure library is also ready for use.

Build both library and now move to our MVC application. Provide the reference of both project (Core and Infrasturcture). Now we create the MVC Application.Remove already existed views, controller, and model. We are going to create our own (don't delete shared folder from Views).

Now create the Controller named CategoriesController.cs, here we show all category from category table. So write the code for Index method (which is default.)

C#
public ActionResult Index()
{
    IRepository<Category> repo = new CategoryRepository();
    return View(repo.GetAll());
}

Now click on method name and add respective view for same (you should familiar with MVC pattern).

The code for display category in Index.cshtml is:

C#
@{ //index.cshtml
    ViewBag.Desc = "MVC3 Razor";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Categories</h2>

    <table>
        <tr>
            <th></th>
            <th>
                Name
            </th>
            <th></th>
        </tr>

    @foreach (var item in Model) { 
    
        <tr>
            <td>
                @Html.ActionLink("Edit", "Edit", new {  id=item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id })
            </td>
            <td>
                @Html.Encode(item.Name)
            </td>
            <td>
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    
    } 

    </table>

    <p>
        @Html.ActionLink("Create New", "Create")
    </p>

Now go to global.aspx.cs and in Register Route method replace default controller name with "Categories". Now run the your MVC application ,you will have a list of all categories. Don't you have any record in database, don't worry we create the page for insert a category.

Add Create method for rendering Create.cshtml:

C#
public ActionResult Create()
{ //this method render Create.cshml
    return View();
}
XML
@{ //Create.cshtml
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>
        Create Category</h2>
    @Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.")
    @using (Html.BeginForm()){
    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Name">
                Name:</label>
            @Html.TextBox("Name")
            @Html.ValidationMessage("Name", "*")
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
     } 
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>

Now press the create new button in Category listing page, you will have a page for insert the category. Before you press Create button we have to create method for saving the data. so add Create method (here method overloading) which handles the post method of this page and get the data using form collection.

Code seems like:

C#
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection formCollection)
{
    string name = formCollection.Get("Name");
    Category category = new Category() { Name = name };

    IRepository<Category> repo = new CategoryRepository();
    repo.Save(category);

    return RedirectToAction("Index");
}

Now enter category name in textbox and press submit button. You can see recently added category in category listing page. Now we work on Edit and delete.

For editing the category add Edit method in CategoriesController.cs, which renders Edit.cshtml.

C#
public ActionResult Edit(Guid id)
{
    //When you click edit link from list you comes here for get particular record
    IRepository<Category> repo = new CategoryRepository();
    return View(repo.GetById(id));
}
XML
@{   // Edit.cshtml
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit Category</h2>

@Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") 

@using (Html.BeginForm()) {

    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Name">Name:</label>
            @Html.TextBox("Name", null, new { @value = Model.Name })
            @Html.ValidationMessage("Name", "*")
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

}

<div>
    @Html.ActionLink("Back to List", "Index") 
</div>

Now we create the method for update the record. Again add this method for update record which handles Post action from Edit.cshtml.

C#
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, FormCollection formCollection)
{
    string name = formCollection.Get("Name");
    Category category = new Category() { Id = id, Name = name };

    IRepository<Category> repo = new CategoryRepository();
    repo.Update(category);

    return RedirectToAction("Index");
}

After clicking on save you will be back on your listing page and can see the modified record.

Now we create add the method for delete. Create this method for the delete the category.

C#
public ActionResult Delete(Guid id)
{
    IRepository<Category> repo = new CategoryRepository();
    repo.Delete(repo.GetById(id));
    return RedirectToAction("Index");
}

Our CRUD operations are over here. If you still have any issues the you can check the source code from attachment.

Points of Interest  

When I started to learn NHibernate using MVC3 with Razor engine, I searched out on Google for sample code but i didn't. Then I found one sample application with aspx then I have made it reference and created same using razor engine.

History

I will enhance this article very shortly.

License

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