Tuesday, August 08, 2006

Tutorial - NHibernate and VS2005 - Part 1

Back on track. Or at least I hope so.

In part 1 my goals are:

  1. create a class Customer holding some archetypical customer fields
  2. create a database with a single table Customer
  3. write enough NHibernate plumbing code to connect to this database and
  4. persist an instance of the Customer class into the database
Not terribly lofty, but achievable. I hope.

Let's get started with
  1. create a class Customer holding some archetypical customer fields
I have installed SQL Server 2005 Express on a machine called, say, BUBBAPC. On this machine I have a single server called, say, BUBBADB (try saying that, it's fun buh-bah-dee-bee hee-hee-hee.) Also, say, I am running this as user BUBBA.

Also assume that my sa account has password sabubba.

Connect to the database either through Microsoft SQL Server Management Studio or with
sqlcmd -S BUBBAPC\BUBBA01 -U sa -P sabubba
Now, dump in the following script:

 use master

 go

 create database nhibernate

 go

 create login [BUBBAPC\BUBBA] from windows

 go

 use nhibernate

 go

 create user [BUBBA] for login [BUBBAPC\BUBBA]

 go

 exec sp_addrolemember 'db_owner', 'BUBBA'

 go


Let's try this out:
sqlcmd -S BUBBAPC\BUBBA01
1> select count(*) from sysobjects
2> go
-----------
1762
(1 rows affected)
1> quit
Wow, fancy.

Now, back to Visual Studio. I'm assuming you've loaded the solution file from Part 0.1.

Add a new class file to NHibernateTest called Customer.cs

Remove all of the autogenerated cruft and replace it with this:

    1 using System;

    2 

    3 namespace NHibernateTest

    4 {

    5     public class Customer

    6     {

    7         #region ID

    8         private int m_ID;

    9         public int ID

   10         {

   11             get { return m_ID; }

   12             set { m_ID = value; }

   13         }

   14         #endregion

   15 

   16         #region Name

   17         private string m_Name;

   18         public string Name

   19         {

   20             get { return m_Name; }

   21             set { m_Name = value; }

   22         }

   23         #endregion

   24     }

   25 }


That's all we need to do for the POD class Customer
Now we need to tell NHibernate what to do with this class. This is all driven by an xml file.

Add an XML File called Customer.hbm.xml.

Drop in this bit of xml:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"

    3     default-lazy="false">

    4   <class

    5       name="NHibernateTest.Customer, NHibernateTest"

    6       table="Customer">

    7     <id name="ID" column="ID" type="Int32">

    8       <generator class="identity" />

    9     </id>

   10     <property name="Name" column="Name" type="String"

   11       length="50"/>

   12   </class>

   13 </hibernate-mapping>


Set the Build Action for Customer.hbm.xml to Embedded Resource.

And now we need to create the underlying table. First, make sure the Server Explorer is visible in Visual Studio. You can get there with - Ctrl-Alt-S or View|Server Explorer.

Right click on Data Connectons|Add Connection...
Data Source: Microsoft SQL Server
Continue

  Server Name: BUBBAPC\BUBBA01
  Log in using Windows Authentication
  Database Name: NHibernate

Right click on Tables|Add New Table...
Add the following columns
  Column NameData TypeAllow Nulls
  IDintNo
  Namevarchar(50)No

Right click on ID and Set Primary Key. in the Column Properties tab find 'Identity Specification' and set Is Identity to Yes. It should look something like this:


Save this. When it asks for the table name enter Customer.

We're circling in now..

Add a reference to the NHibernate Assembly nhibernate.dll

Add an Application Configuration File call App.config to NHibernateTest with this XML:

    1 <?xml version="1.0" encoding="utf-8" ?>

    2 <configuration>

    3   <configSections>

    4     <section name="nhibernate"

    5             type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

    6   </configSections>

    7 

    8   <nhibernate>

    9     <add key="hibernate.connection.provider"

   10       value="NHibernate.Connection.DriverConnectionProvider"/>

   11     <add key="hibernate.dialect"

   12       value="NHibernate.Dialect.MsSql2000Dialect"/>

   13     <add key="hibernate.connection.driver_class"

   14       value="NHibernate.Driver.SqlClientDriver"/>

   15     <add key="hibernate.connection.connection_string"

   16       value="Server=BUBBAPC\BUBBA01;initial catalog=nhibernate;Integrated Security=SSPI"/>

   17   </nhibernate>

   18 </configuration>


Replace the contents of Program.cs with this:

  1 using System;
  2 using System.Diagnostics;
  3 using System.Reflection;
  4 
  5 using NHibernate;
  6 using NHibernate.Cfg;
  7 
  8 namespace NHibernateTest
  9 {
  10    class Program
  11&;;nbsp;   {
  12      static void Main(string[] args)
  13      {
  14        try
  15        {
  16          Configuration cfg = new Configuration ();
  17          cfg.AddAssembly (Assembly.GetExecutingAssembly ().GetName ().Name);
  18 
  19          ISessionFactory factory = cfg.BuildSessionFactory ();
  20 
  21          using (ISession session = factory.OpenSession ())
  22          using (ITransaction transaction = session.BeginTransaction ())
  23          {
  24            Customer customer = new Customer ();
  25            customer.Name = "Joseph Cool";
  26 
  27            session.Save (customer);
  28 
  29            transaction.Commit ();
  30 
  31            Debug.WriteLine ("Success! ID=" + customer.ID);
  32          }
  33        }
  34        catch (Exception e)
  35        {
  36          Debug.WriteLine (e);
  37        }
  38      }
  39    }
  40 }


If you see this error: NHibernate.MappingException: Unknown entity class: NHibernateTest.Customer that means you forgot to update the Build Action for Customer.hbm.xml to Embedded Resource

That's it. C'est fini.

Everytime to run this app you will get another row in Customer.

1 comment:

Anonymous said...

I had an issue because when I created a new table and classes I couldnt get any data from the database until I read this article and saw the comment updateing the Build Action to Embedded Resource and it fixed my issue.

Thanks for a great article!