Skip to main content

NHibernate Introduction

 NHibernate


NHibernate is an open source Object-Relational Mapping (ORM) tool for the .Net platform… and the existing documentation and tutorials that I could find, whilst plentiful, are not aimed at those new to or inexperienced with ORM. This tutorial is based on using Visual Studio (I used 2008 beta 2) and Sql Server, however the database used is almost immaterial (one of the advantages of using an OR mapper).
If you already know what NHibernate and ORM are and you want to use it but just need to know how?  Otherwise, read on.
WTF is ORM?
There is plenty of good stuff out there on what Object-Relational Mapping is, try wikipedia or the intro here (the tutorial is a bit out of date but the explanation is good) or there’s always Google.
However, in a nutshell, ORM is the process of mapping business objects (think OOP) to database relations (read tables). An OR Mapper is a tool that manages this process. There are several different OR Mappers available for .Net however NHibernate seems to have a lot of momentum and a good history as it is based on a port from the original Java version, Hibernate. The reason for using an OR Mapper is that writing SQL sucks, making changes is a pain in the ass and once you’ve started employing some decent OOP practices and are modelling your business domain with real-world objects, you don’t want to cloud your head with SELECTs, JOINs, WHEREs, primary keys, foreign keys and all that RDBMS jazz.
Okay… so what is ORM again?
Imagine you have a simple Contact class (which coincidentally we will do later). Wouldn’t it be nice if you could create a simple tbl_contact, write a little xml file that says “Contact.FirstName maps to tbl_contact.first_name” and then let something else worry about your CRUD (Create, Retrieve, Update and Delete) database logic? All you then have to do is say “Oi NHibernate, Save this Contact for me please”. That’s what you get with NHibernate and many other OR Mappers, it becomes the basis for your “Persistance Layer” or “Data Access Layer” for those who like their OOP terminology. You get to focus on your business objects and “proper programming” and you let NHibernate worry about saving stuff to the database.
Sounds good, show me
Okay so here’s what we’re going to do:
  • Download NHibernate
  • Create a contacts table
  • Create a Contact class in an assembly
  • Write a mapping file between the class and table
  • Setup a web project for NHibernate
  • Use a simple web form to create and save Contacts
So let’s get going…
Download NHibernate
  I’d suggest starting with just the binary zip (2nd link at time of writing). Save it and extract to somewhere you’ll remember.
Create a contacts table
Our contacts are going to be pretty simple, here’s one I made earlier (SQL Server 2000 – you can very easily use any database you’re familiar with just remember to alter some details later) Create a new database and execute the following SQL:
1
2
3
4
5
6
7
CREATE TABLE tbl_contact (
 contact_id BIGINT IDENTITY (1, 1) NOT NULL ,
 first_name VARCHAR(255),
 last_name VARCHAR(255),
 email VARCHAR(255),
 telephone VARCHAR(50)
)
Create a Contact class in an assembly
So we’re going to actually do some coding now, open Visual Studio create a new Class Library (mine’s called ContactDomain) and add a new class called Contact.cs and paste in the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
namespace ContactDomain
{
    public class Contact
    {
        private int _contactId;
        private string _firstName;
        private string _lastName;
        private string _email;
        private string _telephone;
 
        public virtual int ContactId
        {
            get{ return _contactId; }
            set{ _contactId = value; }
        }
 
        public virtual string FirstName
        {
            get{ return _firstName; }
            set{ _firstName = value; }
        }
 
        public virtual string LastName
        {
            get{ return _lastName; }
            set{ _lastName = value; }
        }
 
        public virtual string Email
        {
            get{ return _email; }
            set{ _email = value; }
        }
 
        public virtual string Telephone
        {
            get{ return _telephone; }
            set{ _telephone = value; }
        }
 
        public Contact()
        {
 
        }
    }
}
That’s our Contact class, you could apparently just use public variables but I find it better practice to always use getter/setters.
Write a mapping file between the table and class
This is where the magic happens. It seems the more you can be bothered to read up on mapping files the better. This example is about as basic as you can get but I will add further tutorials to cater for 1:n relationships and other complexities in due course. You can pretty much handle any scenario with mapping files even complex joins (so I’ve read).
To create the mapping file, add an xml file to your project and call it by the same name as your class but with a .hbm.xml extension (I.E. “Contact.hbm.xml”). Paste in the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="ContactDomain"
                   assembly="ContactDomain">
 
    <class name="Contact" table="tbl_contact">
        <id name="ContactId" column="contact_id" type="int">
            <generator class="identity"></generator>
        </id>
 
        <property name="FirstName"  column="first_name" type="String"/>
        <property name="LastName"   column="last_name"  type="String"/>
        <property name="Email"      column="email"      type="String"/>
        <property name="Telephone"  column="telephone"  type="String"/>
    </class>
</hibernate-mapping>
This example is so simple you should be able to tell what’s going on. We’re highlighting the properties of our Contact class and what the equivilent field is from our tbl_contact. We’ll cover more of the intricacies of mapping files in a later article. IMPORTANT: Once saved, select the xml file in the file explorer and view properties, make sure the build action is set to “Embedded Resource” which will ensure the mapping file is available within the assembly which will be referenced later.
Save and build the assembly (Ctrl, Shift + B), this will create your /bin/debug/ContactDomain.dll file which we’ll reference in our web project.
Setup a web project for NHibernate
Create a new web project (mine’s called ContactManager). Open your web.config and add the following below the <configuration> tag:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<configSections>
        <section
          name="nhibernate"
          type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,
 Culture=neutral, PublicKeyToken=b77a5c561934e089"
    />
    </configSections>
 
    <nhibernate>
        <add
          key="hibernate.connection.provider"
          value="NHibernate.Connection.DriverConnectionProvider"
    />
        <add
          key="hibernate.dialect"
          value="NHibernate.Dialect.MsSql2000Dialect"
    />
        <add
          key="hibernate.connection.driver_class"
          value="NHibernate.Driver.SqlClientDriver"
    />
        <add
          key="hibernate.connection.connection_string"
          value="Data Source=myServer;Initial Catalog=myDatabase;Persist Security Info=True;
User ID=myDbUsername;Password=myDbPassword;"
    />
    </nhibernate>
Obviously ammend the connection string to suit your database settings. Next right click your project in the File Explorer and choose “Add Reference”. Now browse to your previous assembly and add it.
Use a simple web form to create and save Contacts
Firstly we need to add a reference to NHibernate.dll, to do this right click on your project, click Add Reference, browse to where you downloaded NHibernate and find /bin/.Net2.0/Nhibernate.dll and click Add.
If there isn’t already a Default.aspx, add one and paste in the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/
xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="lblFirstName" runat="server" Text="First Name:"></asp:Label><asp:TextBox ID="txtFirstName"
 runat="server"></asp:TextBox><br />
        <asp:Label ID="lblLastName" runat="server" Text="Last Name:"></asp:Label><asp:TextBox ID="txtLastName" 
runat="server"></asp:TextBox><br />
        <asp:Label ID="lblEmail" runat="server" Text="Email:"></asp:Label><asp:TextBox ID="txtEmail" 
runat="server"></asp:TextBox><br />
        <asp:Label ID="lblTelephone" runat="server" Text="Telephone:"></asp:Label><asp:TextBox ID="txtTelephone"
 runat="server"></asp:TextBox><br />
        <asp:Button ID="btnSaveContact" runat="server" Text="Save Contact" OnClick="btnSaveContact_Click" />
    </div>
    </form>
</body>
</html>
Then in the code-behind paste this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ContactDomain;
 
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
 
    protected void btnSaveContact_Click(object sender, EventArgs e)
    {
        // setup nhibernate configuration
        NHibernate.Cfg.Configuration config = new NHibernate.Cfg.Configuration();
        // add our assembly
        config.AddAssembly("ContactDomain");
        // setup nhibernate session
        NHibernate.ISessionFactory factory = config.BuildSessionFactory();
        NHibernate.ISession session = factory.OpenSession();
        // start nhibernate transaction
        NHibernate.ITransaction transaction = session.BeginTransaction();
 
        // create contact
        Contact contact = new Contact();
        contact.FirstName = txtFirstName.Text;
        contact.LastName = txtLastName.Text;
        contact.Email = txtEmail.Text;
        contact.Telephone = txtTelephone.Text;
 
        // Tell NHibernate that this object should be saved
        session.Save(contact);
 
        // commit all of the changes to the DB and close the ISession
        transaction.Commit();
        session.Close();
    }
}
That’s It!
Run the web project, fill in the boxes and hit save. You won’t see anything other than the page refresh but if you then query your database you should see you’ve saved a new contact!
There’s plenty more you can do with NHibernate and now we’ve got the setup out of the way you should find it becomes a huge time-saver for your data-driven projects.


Comments

Popular posts from this blog

NHibernate QueryOver Class And Projection....

Introduction The ICriteria API is NHibernate's implementation of Query Object . NHibernate 3.0 introduces the QueryOver api, which combines the use of Extension Methods and Lambda Expressions (both new in .Net 3.5) to provide a statically typesafe wrapper round the ICriteria API. QueryOver uses Lambda Expressions to provide some extra syntax to remove the 'magic strings' from your ICriteria queries. So, for example: .Add(Expression.Eq("Name", "Smith")) becomes: .Where<Person>(p => p.Name == "Smith") With this kind of syntax there are no 'magic strings', and refactoring tools like 'Find All References', and 'Refactor->Rename' work perfectly. Note: QueryOver is intended to remove the references to 'magic strings' from the ICriteria API while maintaining it's opaqueness. It is not a LINQ provider; NHibernate 3.0 has a built-in

Passing Data from View to Controller Using Ajax Example Jquery

Jquery       $ ( '#btnSaveComments' ). click ( function () { var comments = $ ( '#txtComments' ). val (); var selectedId = $ ( '#hdnSelectedId' ). val (); $ . ajax ({ url : '<%: Url.Action("SaveComments")%>' , data : { 'id' : selectedId , 'comments' : comments }, type : "post" , cache : false , success : function ( savingStatus ) { $ ( "#hdnOrigComments" ). val ( $ ( '#txtComments' ). val ()); $ ( '#lblCommentsNotification' ). text ( savingStatus ); }, error : function ( xhr , ajaxOptions , thrownError ) { $ ( '#lblCommentsNotification' ). text ( "Error encountered while saving the comments." ); } }); });     Controller    [ HttpPost ] public ActionResult SaveComments ( int id , string com

The Core Concepts of Angular -- Jithin CJ

I started to learn angular from 2016, I was very curious about the celibacy of this super hero. From my initial understanding is like, the power of angular is only limited on " html decoration "  But this JavaScript framework has the potential to re-define conventional html-css patterns . Modern browsers support for things like modules, classes, lambdas, generators, etc. These features fundamentally transform the JavaScript programming experience. But big changes aren't constrained merely to JavaScript. Web Components are on the horizon. The term Web Components usually refers to a collection of four related W3C specifications: Custom Elements - Enables the extension of HTML through custom tags.  HTML Imports - Enables packaging of various resources (HTML, CSS, JS, etc.).  Template Element - Enables the inclusion of inert HTML in a document.  Shadow DOM - Enables encapsulation of DOM and CSS.  Developers can create fully encapsulated (Shadow DOM) declar