Wednesday, April 25, 2007

Basics of NHibernate

NHibernate: An Object to Relational Mapping Tool.



This post is to just let you know how to start working with NHibernate a tool that let you save your real world objects directly to your relational database.
It handles persisting plain .NET objects to and from an underlying relational database. Given an XML description of your entities and relationships, NHibernate automatically generates SQL for loading and storing the objects.

For detailed description and downloading NHibernate please visit the site:
http://www.hibernate.org
However the following lines let you know how you can start working with NHibernate.
The environment that I am choosing is .NET 2003, SQL Server 2000, NHibernateContrib-1.0.4.0.zip, Language : C#

First create a website and add the reference of NHibernate.dll found under the folder NHibernateContrib-1.0.4.0\bin\

Add reference of NHibernate.dll and add the rest of the dlls in your projects bin directory.

So now you are able to add NHibernate code but remember to build to check whether you are using the right version of NHibernate or not…..

Ok, Now lets start working with a class whose object you want to store in your database.

I am naming this class as Cat.
FIRST PERSISTENT CLASS : CAT

using System;

namespace testa
{
///
/// Summary description for Cat.
///

public class Cat
{
private string id;
private string name;
private char sex;
private float weight;

public string Id
{
get
{
return id;
}
set
{
id = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public char Sex
{
get
{
return sex;
}
set
{
sex = value;
}
}
public float Weight
{
get
{
return weight;
}
set
{
weight = value;
}
}

public Cat()
{
//
// TODO: Add constructor logic here
//
}
}
}

This is a normal C# class with some properties whose object you want to store to your database.

MAPPING THE CAT
Create an xml file but remember to put it in the same directory where your class resides and name it Cat.hbm.xml. The content of Cat.hbm.xml will look like this:

Do remember to make the Cat.hbm.xml an embed reource in your application by clicking on the Cat.hbm.xml and pushing F4 in your keyboard and then choose Build Action as: Embedded Resource

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="testa" assembly="testa">
<class name="Cat" table="Cat">
<id name="Id">
<column name="CatId" sql-type="char(30)" not-null="true" />
<generator class="uuid.hex" />
</id>
<property name="Name">
<column name="Name" length="16" not-null="true" />
</property>
<property name="Sex" />
<property name="Weight" />
</class>
</hibernate-mapping>


The table cat in the database will look like this:
Column Type
CatId char(32)
Name nvarchar(16)
Sex char(1)
Weight float

Meanwhile something about NHibernate’s ISession. Its an interface that let you store and retrieve objects from the database.
To get ISession from the ISessionFactory:

ISessionFactory sessionFactory =
new Configuration().Configure().BuildSessionFactory();

An ISessionFactory is usually only built once, e.g. at startup inside Application_Start event handler. This also means you should not keep it in an instance variable in your ASP.NET pages, but in some other location. Furthermore, we need some kind of Singleton, so we can access the ISessionFactory easily in application code. The approach shown next solves both problems: configuration and easy access to a ISessionFactory.

We will do this by Impleting a helper calss that will take care for all the Sessions open for the applications:
Implementing the NHibernate Helper Class:

using System;
using System.Web;
using NHibernate;
using NHibernate.Cfg;

namespace testa
{
///
/// Summary description for NHibernateHelper.
///

public sealed class NHibernateHelper
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;

static NHibernateHelper()
{
sessionFactory = new Configuration().Configure().BuildSessionFactory();
}

public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;

if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}

public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;

if (currentSession == null)
{
return;
}

currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}

public static void CloseSessionFactory()
{
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
}
}

Now if we have all the sessions available we can use it for persisting our objects.

Make a webform from where you want to save your objects.
I called it CallToHibernate.aspx and in the Codebehind class use the following code.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using NHibernate;
using NHibernate.Cfg;

namespace testa
{
///
/// Summary description for CallToHibernate.
///

public class CallToHibernate : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
ISession currentSession = NHibernateHelper.GetCurrentSession();
ITransaction tx = currentSession.BeginTransaction();

Cat myCat = new Cat();

myCat.Name = "Nina";
myCat.Sex = 'F';
myCat.Weight = 32.23f;

// To persist data to the database
currentSession.SaveOrUpdate(myCat); // or call only the Save method
/* To load data based upon the identifier.
Use the currentSession.Load(object type, object identifier) method.
* */
tx.Commit();

NHibernateHelper.CloseSession();
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}


Now just open your browser and call the CalltoHibernate.aspx page and see the database. You have a Cat in your database named Nina.

This level of abstraction is really appreciable in real world applications.

For any query mail me at
shashank@bnkinfotech.com

Monday, April 23, 2007

Background Worker Class in .NET

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

and here is an example how you can do this:

Step 1: Create an instance of BackgroundWorker class:

private BackgroundWorker bw = new BackgroundWorker();

Step 2: Define DoWorkEventHandler and RunWorkerCompleted events before Page_Render events :

protected override void OnPreLoad(EventArgs e)
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);

bw.RunWorkerAsync();

bw.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

}

void bw_DoWork(object sender, DoWorkEventArgs de)
{
// Do your background work here
}

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BackgroundWorker bgworker = sender as BackgroundWorker;
// Finalization of your backgroundworker
}

Step 4: Also set Async="true" on your aspx page.

Thats it your background worker instance is ready to work.
To read more about BackGroundWorker class go to this link