Pages

Tuesday, January 17, 2012

Simple Example of NHibernate and SQL Server 2008

In this article, i will create a simple application that implent NHibernate, and in database side, i will use SQL Server 2008. What is NHibernate ? I will not explain it in there, so many explanation what it is in internet, like in here.
You can download latest NHibernate version here.
First, i will create a simple database that have just one table (and i added some record in there):
This is the DDL
1create table ACCOUNT (
2   ACCID                int         identity(1,1)       not null,
3   USERNAME             varchar(50)                     null,
4   PASS                 varchar(50)                     null,
5   constraint PK_ACCOUNT primary key nonclustered (ACCID)
6)
Hmm.. what is Identity(1,1)  mean ??? It is mean we will set ACCID attribute, the primary key, to become autonumbered, the value will be added automatically incrementing from 1, 2, 3, … and so on.
Next step, we will create simple solution in Visual Studio 2008 SP1 (remember … to connect to SQL Server 2008, your Visual Studio 2008 must be Service Pack 1 ).

Add some references
  1. NHibernate.dll (NHibernate library)
  2. NHibernate.ByteCode.LinFu.dll (for lazy loading)
  3. System.configuration


Test your connection with database using Server Explorer


Do not forget to copy the connection string…

For my example, my database connection string is :  ]
Data Source=WIRTH;Initial Catalog=TestNHibernate;User ID=azer89;Password=azer89
Nexttt !!!! create an App.config file in your project (Just Right click your project, Add, New Item, and Application Configuration File)

Set your App.config like this :
01xml version="1.0" encoding="utf-8" ?>
02<configuration>
03  <configSections>
04    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
05  configSections>
06  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
07    <session-factory>
08      <property name="connection.provider">NHibernate.Connection.DriverConnectionProviderproperty>
09      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriverproperty>
10      <property name="connection.connection_string">Data Source=WIRTH;Initial Catalog=TestNHibernate;User ID=azer89;Password=azer89property>
11      <property name="dialect">NHibernate.Dialect.MsSql2008Dialectproperty>
12      <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFuproperty>
13      <mapping assembly="NHibernateTest"/>
14    session-factory>
15  hibernate-configuration>
16configuration>
You must pay attention in property connection.connection_string and dialect in code above. Add a model class similar to Account Table, its fields must be similar too

Your Account.cs should be like this :
01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05 
06namespace NHibernateTest
07{
08    class Account
09    {
10        private int accId;
11        private string username;
12        private string pass;
13 
14        public virtual int AccId
15        {
16            get { return accId; }
17            set { accId = value; }
18        }
19 
20        public virtual string UserName
21        {
22            get { return username; }
23            set { username = value; }
24        }
25 
26        public virtual string Pass
27        {
28            get { return pass; }
29            set { pass = value; }
30        }
31    }
32}
After creating Account class, we will create map to Account Table using XML file, so NHibernate will know that Account class in application will map to Account Table in database. The XML filename will be “Account.nbm.xml”
01xml version="1.0" encoding="utf-8" ?>
02<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NHibernateTest" assembly="NHibernateTest">
03  <class name="Account" table="ACCOUNT" lazy="false">
04    <id name="AccId">
05      <column name="ACCID"/>
06      <generator class="native"/>
07    id>
08    <property name="UserName">
09      <column name="username"/>
10    property>
11    <property name="Pass">
12      <column name="pass"/>
13    property>
14  class>
15hibernate-mapping>
Look at generator class, its value is “native”, it is because we have set ACCID column into autoincrement. Oh yeah, Build Action for hbm.xml file must be “Embedded Resource”

Next step is to create persistence class, we will name it NHibernateHelper.cs
01using System.Reflection;
02using NHibernate;
03using NHibernate.Cfg;
04 
05namespace NHibernateTest
06{
07    public sealed class NHibernateHelper
08    {
09        private static ISessionFactory SessionFactory;
10 
11        private static void OpenSession()
12        {
13            Configuration configuration = new Configuration();
14            configuration.AddAssembly(Assembly.GetCallingAssembly());
15            SessionFactory = configuration.BuildSessionFactory();
16        }
17 
18        public static ISession GetCurrentSession()
19        {
20            if (SessionFactory == null)
21                NHibernateHelper.OpenSession();
22 
23            return SessionFactory.OpenSession();
24        }
25 
26        public static void CloseSessionFactory()
27        {
28            if (SessionFactory != null)
29                SessionFactory.Close();
30        }
31    }
32}
Since ISessionFactory is expensive to create (it almost take one second in my computer !!!) we will create one object of ISessionFactory, otherwise with ISession, it is very cheap to create, so we can create it very ofter in your application. We will test the code :
01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05using NHibernate;
06 
07namespace NHibernateTest
08{
09    class Program
10    {
11        static void Main(string[] args)
12        {
13            string username = "reza";
14            string pass = "reza";
15 
16            ISession session = NHibernateHelper.GetCurrentSession();
17            IQuery query = session.CreateQuery("FROM Account WHERE username = :name  AND pass = :pass ");
18            query.SetString("name", username);
19            query.SetString("pass", pass);
20            IList acc = query.List();
21            session.Close();
22            if (acc.Count == 0)
23                Console.WriteLine("Cannot find specified user");
24            else
25                Console.WriteLine("Found " + acc[0].UserName);
26 
27            Console.ReadKey();
28 
29        }
30    }
31}
It is Work !!!

No comments: