Pages

Saturday, March 20, 2010

My First NHibernate application

  1. Download NHibernate from http://www.nhforge.org
  2. Create New Visual Studio project (i name it NHibernateDemo)
  3. Add an assembly reference to NHibernate.dll

    For this example I am using NHibernate-2.1.2
    Also copy files from NHibernate-2.1.2.GA-bin\Required_For_LazyLoading\LinFu folder
    which contains supporting files for lazy loading to your Bin folder.
  4. Create database tables
    tblEmployee - Maintain employee information
    tblSkill - Maintain simple list of skills with ID and Title
    tblEmployeeSkill - Mapping table of employee and skill (many-to-many relation)

    image001
    CREATE TABLE tblEmployee(
    EmployeeID int IDENTITY(1,1) NOT NULL,
    FistName nchar(50),
    LastName nchar(50)
    DOB datetime,
    HomeAddress nchar(100)
    )
    
    
    CREATE TABLE tblSkill(
    SkillID int IDENTITY(1,1) NOT NULL,
    Title nchar(50)
    )
    
    
    CREATE TABLE  tblEmployeeSkills(
    EmployeeID int NOT NULL,
    SkillID int NOT NULL,
    AssignedDate datetime
    )   
    

  5. Create Business classes


    image003


    public class Employee
    {
    public virtual int EmployeeID { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime DateOfBirth { get; set; }
    public virtual string HomeAddress { get; set; }
    
    public virtual IList Skills { get; set; }
    }
    
    public class Skill
    {
    public virtual int SkillID { get; set; }
    public virtual string Title { get; set; }
    }      
    

    Every property of our class should be virtual.

    Because if you need lazy loading to be enabled you must mark each property as virtual. Then the nhibernate can create required proxy class for our class types. For more info about this please read this post by Davi Brion.

    Also the collection types should be IList<> or ISet. (e.g. List)
  6. Create NHibernate mappings (hbm)
    Create new XML file and name it DemoMappings.hbm.xml

    (For this example i am using a single file to contain all the classes mappings. But you can create any number of individual XML files for each mapping)

    Also remember to set Build Action property to Embedded Resource of DemoMappings.hbm.xml file.

    TIP : For visual studio intelisence for XML file please set Schema of the XML file to nhibernate-mapping.xsd . which can be found in NHibernate bin folder.


    image005
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    namespace="NHibernateDemo.BusinessObjects" assembly="NHibernateDemo">
    
    <class proxy="Skill" table="tblSkill" name="Skill">
    <id name="SkillID" column="SkillID" type="Int32">
    <generator class="identity"></generator>
    </id>
    <property name="Title" column="Title" type="string" length="50"></property>
    </class>
    
    
    <class proxy="Employee" table="tblEmployee" name="Employee" lazy="true">
    <id name="EmployeeID" column="EmployeeID" type="Int32">
    <generator class="identity"></generator>
    </id>
    
    <property name="FirstName" column="FirstName" type="String" length="50"></property>
    <property name="LastName" column="LastName" type="String" length="50"></property>
    <property name="DateOfBirth" column="DOB" type="DateTime"></property>
    <property name="HomeAddress" column="HomeAddress" type="String"></property>
    
    <bag table="tblEmployeeSkills" name="Skills" lazy="false">
    <key column="EmployeeID"></key>
    <many-to-many class="Skill" column="SkillID"></many-to-many>
    </bag>
    </class>
    </hibernate-mapping>
    
  7. Configure NHibernate

    Create hibernate.cfg.xml and set Copy to Output to Copy Always. And copy paste following,

    (If you didn’t do above then you will get error somewhat like: An exception occurred during configuration of persistence layer.)

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
    <property name="connection.provider">
    NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">
    Data Source=.\sqlexpress;Initial Catalog=DemoDB;Integrated Security=True
    </property>
    <property name="show_sql">true</property>
    </session-factory>
    </hibernate-configuration>
    

    Tip : List of supported databases and connection configuration settings
    http://community.jboss.org/wiki/DatabasessupportedbyNHibernate

  8. Creating a Employee using NHibernate

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using NHibernate.Cfg;
    using NHibernateDemo.BusinessObjects;
    using NHibernate;
    
    namespace NHibernateDemo
    {
    class Program
    {
    private static ISessionFactory _sessionFactory;
    
    private static ISessionFactory SessionFactory
    {
    get
    {
    if (_sessionFactory == null)
    {
    var configuration = new Configuration();
    configuration.Configure();
    configuration.AddAssembly(typeof(Employee).Assembly);
    _sessionFactory = configuration.BuildSessionFactory();
    }
    return _sessionFactory;
    }
    }
    
    public static ISession OpenSession()
    {
    return SessionFactory.OpenSession();
    }
    
    static void Main(string[] args)
    {
    Employee employee = new Employee()
    {
    FirstName = "Dilhan",
    LastName = "Jayathilaka",
    DateOfBirth = DateTime.Now,
    HomeAddress = "Some address."
    };
    
    employee.Skills = new List();
    employee.Skills.Add(new Skill() { SkillID = 1 });
    
    using (ISession session = OpenSession())
    {
    using (ITransaction transaction =
    session.BeginTransaction())
    {
    session.Save(employee);
    transaction.Commit();
    }
    }
    }
    }
    }

    Tip: creating ISessionFactory is an expensive process and avoid creating ISessionFactory more than one instance per application. As shown above you can create static variable to keep it for entire life of the application. ISession is a light wait and you can create it for every action in your application.

No comments: