Creating a NHibernate session to access database within ASP.NET

Exclusive offer: get 50% off this eBook here
NHibernate 2 Beginner's Guide

NHibernate 2 Beginner's Guide — Save 50%

Rapidly retrieve data from your database into .NET objects

£16.99    £8.50
by Aaron Cure | May 2010 | .NET Open Source

NHibernate is an open source object-relational mapper, or simply put, a way to rapidly retrieve data from your database into standard .NET objects. This article teaches you how to create NHibernate sessions, which use database sessions to retrieve and store data into the database.

In this article by Aaron B. Cure, author of Nhibernate 2 Beginner's Guide we'll talk about:

  • What is an NHibernate session?
  • How does it differ from a regular database session?
  • Retrieving and committing data
  • Session strategies for ASP.NET

(Read more interesting articles on Nhibernate 2 Beginner's Guide here.)

What is an NHibernate session?

Think of an NHibernate session as an abstract or virtual conduit to the database. Gone are the days when you have to create a Connection, open the Connection, pass the Connection to a Command object, create a DataReader from the Command object, and so on.

With NHibernate, we ask the SessionFactory for a Session object, and that's it. NHibernate handles all of the "real" sessions to the database, connections, pooling, and so on. We reap all the benefits without having to know the underlying intricacies of all of the database backends we are trying to connect to.

Time for action – getting ready

Before we actually connect to the database, we need to do a little "housekeeping". Just a note, if you run into trouble (that is, your code doesn't work like the walkthrough), then don't panic. See the troubleshooting section at the end of this Time for action section.

  1. Before we get started, make sure that you have all of the Mapping and Common files and that your Mapping files are included as "Embedded Resources". Your project should look as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  2. The first thing we need to do is create a new project to use to create our sessions. Right-click on the Solution 'Ordering' and click on Add | New Project.

    Creating a NHibernate session to access database within ASP.NET

  3. For our tests, we will use a Console Application and name it Ordering.Console. Use the same location as your previous project.

    Creating a NHibernate session to access database within ASP.NET

  4. Next, we need to add a few references. Right-click on the References folder and click on Add Reference. In VB.NET, you need to right-click on the Ordering.Console project, and click on Add Reference.

    Creating a NHibernate session to access database within ASP.NET

  5. Select the Browse tab, and navigate to the folder that contains your NHibernate dlls. You should have six files in this folder. Select the NHibernate.dll, Castle.Core.dll, Castle.DynamicProxy2.dll, Iesi.Collections.dll, log4net.dll, and NHibernate.ByteCode.Castle.dll files, and click on OK to add them as references to the project.

    Creating a NHibernate session to access database within ASP.NET

  6. Right-click on the References folder (or the project folder in VB.NET), and click on Add Reference again. Select the Projects tab, select the Ordering.Data project, and click on OK to add the data tier as a reference to our console application.

    Creating a NHibernate session to access database within ASP.NET

  7. The last thing we need to do is create a configuration object. We will discuss configuration in a later chapter, so for now, it would suffice to say that this will give us everything we need to connect to the database. Your current Program.cs file in the Ordering.Console application should look as follows:

    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Ordering.Console
    {
    class Program
    {
    static void Main(string[] args)
    {
    }
    }
    }

    Or, if you are using VB.NET, your Module1.vb file will look as follows:

    Module Module1
    Sub Main()
    End Sub
    End Module

  8. At the top of the file, we need to import a few references to make our project compile. Right above the namespace or Module declarations, add the using/Imports statements for NHibernate, NHibernate.Cfg, and Ordering.Data:

    using NHibernate;
    using NHibernate.Cfg;
    using Ordering.Data;

    In VB.NET you need to use the Imports keyword as follows:

    Imports NHibernate
    Imports NHibernate.Cfg
    Imports Ordering.Data

  9. Inside the Main() block, we want to create the configuration object that will tell NHibernate how to connect to the database. Inside your Main() block, add the following code:

    Configuration cfg = new Configuration();
    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionProvider,
    typeof(NHibernate.Connection.DriverConnectionProvider)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect,
    typeof(NHibernate.Dialect.MsSql2008Dialect)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver,
    typeof(NHibernate.Driver.SqlClientDriver)
    .AssemblyQualifiedName);

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString,
    "Server= (local)\\SQLExpress;Database=
    Ordering;Trusted_Connection=true;");

    cfg.Properties.Add(NHibernate.Cfg.Environment.
    ProxyFactoryFactoryClass, typeof
    (NHibernate.ByteCode.LinFu.ProxyFactoryFactory)
    .AssemblyQualifiedName);

    cfg.AddAssembly(typeof(Address).AssemblyQualifiedName);

    For a VB.NET project, add the following code:

    Dim cfg As New Configuration()
    cfg.Properties.Add(NHibernate.Cfg.Environment. _
    ConnectionProvider, GetType(NHibernate.Connection. _
    DriverConnectionProvider).AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect, _
    GetType(NHibernate.Dialect.MsSql2008Dialect). _
    AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver, _
    GetType(NHibernate.Driver.SqlClientDriver). _
    AssemblyQualifiedName)

    cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString, _
    "Server= (local)\SQLExpress;Database=Ordering; _
    Trusted_Connection=true;")

    cfg.Properties.Add(NHibernate.Cfg.Environment. _
    ProxyFactoryFactoryClass, GetType _
    (NHibernate.ByteCode.LinFu.ProxyFactoryFactory). _
    AssemblyQualifiedName)

    cfg.AddAssembly(GetType(Address).AssemblyQualifiedName)

  10. Lastly, right-click on the Ordering.Console project, and select Set as Startup Project, as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  11. Press F5 or Debug | Start Debugging and test your project. If everything goes well, you should see a command prompt window pop up and then go away. Congratulations! You are done!
  12. However, it is more than likely you will get an error on the line that says cfg.AddAssembly(). This line instructs NHibernate to "take all of my HBM.xml files and compile them". This is where we will find out how well we handcoded our HBM.xml files.

    The most common error that will show up is MappingException was unhandled. If you get a mapping exception, then see the next step for troubleshooting tips.

    Creating a NHibernate session to access database within ASP.NET

  13. Troubleshooting: NHibernate will tell us where the errors are and why they are an issue. The first step to debug these issues is to click on the View Detail link under Actions on the error pop up. This will bring up the View Detail dialog, as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  14. If you look at the message, NHibernate says that it Could not compile the mapping document: Ordering.Data.Mapping.Address.hbm.xml. So now we know that the issue is in our Address.hbm.xml file, but this is not very helpful. If we look at the InnerException, it says "Problem trying to set property type by reflection". Still not a specific issue, but if we click on the + next to the InnerException, I can see that there is an InnerException on this exception.

    The second InnerException says "class Ordering.Data.Address, Ordering.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null not found while looking for property: Id".

    Now we are getting closer. It has something to do with the ID property. But wait, there is another InnerException. This InnerException says "Could not find a getter for property 'Id' in class 'Ordering.Data.Address'". How could that be? Looking at my Address.cs class, I see:

    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace Ordering.Data
    {
    public class Address
    {
    }
    }

    Oops! Apparently I stubbed out the class, but forgot to add the actual properties. I need to put the rest of the properties into the file, which looks as follows:

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Ordering.Data
    {
    public class Address
    {
    #region Constructors
    public Address() { }
    public Address(string Address1, string Address2, string
    City, string State, string Zip)
    : this()
    {
    this.Address1 = Address1;
    this.Address2 = Address2;
    this.City = City;
    this.State = State;
    this.Zip = Zip;
    }
    #endregion
    #region Properties
    private int _id;
    public virtual int Id
    {
    get { return _id; }
    set { _id = value; }
    }
    private string _address1;
    public virtual string Address1
    {
    get { return _address1; }
    set { _address1 = value; }
    }
    private string _address2;
    public virtual string Address2
    {
    get { return _address2; }
    set { _address2 = value; }
    }
    private string _city;
    public virtual string City
    {
    get { return _city; }
    set { _city = value; }
    }
    private string _state;
    public virtual string State
    {
    get { return _state; }
    set { _state = value; }
    }
    private string _zip;
    public virtual string Zip
    {
    get { return _zip; }
    set { _zip = value; }
    }
    private Contact _contact;
    public virtual Contact Contact
    {
    get { return _contact; }
    set { _contact = value; }
    }
    #endregion
    }
    }

  15. By continuing to work my way through the errors that are presented in the configuration and starting the project in Debug mode, I can handle each exception until there are no more errors.

What just happened?

We have successfully created a project to test out our database connectivity, and an NHibernate Configuration object which will allow us to create sessions, session factories, and a whole litany of NHibernate goodness!

NHibernate 2 Beginner's Guide Rapidly retrieve data from your database into .NET objects
Published: May 2010
eBook Price: £16.99
Book Price: £27.99
See more
Select your format and quantity:

(Read more interesting articles on Nhibernate 2 Beginner's Guide here.)

What is a session factory?

The NHibernate framework uses the abstract factory pattern (see http://en.wikipedia.org/wiki/Abstract_factory_pattern) for creating sessions, and this factory is created from a Configuration object.

The following line of code builds a Session Factory object from our configuration (cfg) object that we'll use to create sessions:

ISessionFactory sessionFactory = cfg.BuildSessionFactory();

From now on, when we want to create a session, we just ask the session factory to open a session for us as follows:

ISession session = sessionFactory.OpenSession();

In addition to opening the session, we want to wrap our statements in a "transaction" to decrease database overhead. I know what you are thinking, wouldn't creating a transaction for every statement actually INCREASE database overhead? In reality, the database already uses implicit transactions for every call we make, so by explicitly telling it to create a single transaction for all of our operations, we are actually reducing the number of calls it makes. To create a transaction for our session, all we need to do is tell the session to begin a transaction for us:

ITransaction tx = session.BeginTransaction();

Creating your first session

Sessions in NHibernate aren't really too tricky, but they are INCREDIBLY powerful. With an NHibernate session, I can perform all of the CRUD (Create, Retrieve, Update, and Delete) operations with ease. Consider the following example:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
Contact contact = new Contact("Joe", "Jones", "jj@nhibernate.com");
session.Save(contact);
tx.Commit();

With five short lines of code, we created a new contact and stored it into the database. The first two lines creates a session from the session factory and start a transaction, the third line creates the contact object from the Contact class that we created, and the last two lines commit it to the database. What if we wanted to add an address before we saved it? We would have to include another three lines of code as follows:

ISession session = sessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
Contact contact = new Contact("Joe", "Jones", "jj@nhibernate.com");
Address address = new Address("123 USA St", null,
"MainTown", "IL", "80305");
contact.Addresses = new List<Address>();
contact.Addresses.Add(address);
session.SaveOrUpdate(contact);
tx.Commit();

All we need to do is create the Address object, attach it to the contact object, and when we save the contact, the address also gets saved—automagically!

Instead of having to instantiate the List on every object every time you use it, put some code in the getter of your property to handle it. The code for the Addresses property is as follows:

private IList<Address> _addresses;
public virtual IList<Address> Addresses
{
get
{
if (_addresses == null)
_addresses = new List<Address>();
return _addresses;
}
set
{
_addresses = value;
}
}

Why in the getter, you may ask? Simple, when you call contact.Addresses.Add(), it calls the getter of the contact.Addresses to retrieve the collection before it calls Add() on it. Our code says "if it's null, create a new list, then return it".

Did you notice that we used the .SaveOrUpdate() construct this time? When we create a new object, we can call .Save() to commit it to the database, and after we update it, we can call .Update(). However, if we don't want to be bothered whether it's new or not, we can just call .SaveOrUpdate() and let NHibernate determine if it is new and how to handle it appropriately.

Why do we call .Commit()?

I'm sure you are wondering why we keep calling .Commit() after we call .Save(). Basically, .Commit() closes our transaction and synchronizes the cached objects with the database.

In its simplest configuration, NHibernate uses a first level cache (or the session cache) to store objects. When you first query an object from the database, it is placed into this cache.

If you haven't told NHibernate to update or delete an object from the database, and it has already been cached, then it will pull this object from the cache rather than round-tripping to the database, improving performance.

By calling .Commit(), we let NHibernate know that we have updated the record(s) in the transaction and that it should persist them to the database.

NHibernate session versus database session?

An NHibernate session encapsulates and abstracts a database session. When we use NHibernate, we don't have to be concerned with many of the operations of the database to include SQL statements and even session manipulation. We let the session factory take care of all that database headache, and we just sit back and smile.

Time for action – creating a session and doing some CRUD

Now it's time to get to the real meat! We have spent the last four chapters "getting ready", and now we will actually create some data. Just like before, if you run into trouble (doesn't work like the walkthrough), see the troubleshooting section at the end of this Time for action.

  1. Open the Program.cs or Module1.vb from the last Time for action, and scroll to the line that says cfg.AddAssembly(typeof(Address).Assembly). On a new line, add the following code:

    ISessionFactory sessionFactory = cfg.BuildSessionFactory();

    In VB.NET, use this code:

    Dim sessionFactory As ISessionFactory = cfg.BuildSessionFactory()

  2. Press F5 or Debug | Start Debugging and test your project. If everything goes well, once again a command prompt window will pop up and then go away. If you happen to get an InvalidProxyTypeException, as shown in the following screenshot, it usually has to do with a property not being marked as "virtual" or "Overridable".

    Creating a NHibernate session to access database within ASP.NET

  3. If this is your issue, then change your property to include the virtual or Overridable keyword as follows:

    private int _id;
    public virtual int Id
    {
    get { return _id; }
    set { _id = value; }
    }

    Or in VB.NET:

    Private _id As Integer
    Public Overridable Property Id() As Integer
    Get
    Return _id
    End Get
    Set(ByVal value As Integer)
    _id = value
    End Set
    End Property

  4. Once your project is able to create a session factory without throwing any errors, we are ready to go! Add the following code to your project and we can create a contact object and commit it to the database with only four lines of code:

    ISession session = sessionFactory.OpenSession();
    ITransaction tx = session.BeginTransaction();
    Contact contact = new Contact("George", "Washington",
    "gw@usa.gov");
    session.Save(contact);
    tx.Commit();

    Or in VB.NET, it will be as follows:

    Dim session As ISession = sessionFactory.OpenSession()
    Dim tx as ITransaction = session.BeginTransaction()
    Dim contact As New Contact("George", "Washington", "gw@usa.gov")
    session.Save(contact)
    tx.Commit()

  5. Did it work? We have two ways of finding out, namely, using NHibernate or using SQL Server. Let's try SQL Server first. Open SSMS, and click on the Ordering database, then on New Query in the toolbar.

    Creating a NHibernate session to access database within ASP.NET

  6. In the resulting query window, type the following query and either hit F5 or click on the Execute button.

    select * from Contact

  7. The previous query should return one (or more, depending on how many times you ran the project) row(s). The returned rows should look as shown in the following screenshot:

    Creating a NHibernate session to access database within ASP.NET

  8. If we wanted to execute the same query from NHibernate, then we can add this code. Once we have the IList of contact objects, we can look at the .Count property of the contacts object to see how many items we retrieved. This can be done as follows:

    ICriteria crit = session.CreateCriteria(typeof(Contact));
    IList<Contact> contacts = crit.List<Contact>();
    int contactCount = contacts.Count;

    Once again, in VB.NET:

    Dim crit As ICriteria = session.CreateCriteria(GetType(Contact))
    Dim contacts As IList(Of Contact) = crit.List(Of Contact)()
    Dim contactCount as Integer = contactCount.Count

    ICriteria is used to query and filter data.

  9. If we wanted to remove the objects we created, we can just iterate through them and call Delete(), while passing in each object. Add the following code into your project, and let's remove our contacts:

    foreach (Contact ctc in contacts)
    {
    session.Delete(ctc);
    }
    tx.Commit();

    In VB.NET, it would look more like this:

    For Each ctc As Contact In contacts
    session.Delete(ctc)
    Next
    tx.Commit()

  10. Execute the code by pressing F5.
  11. Go back to SSMS, and execute your select query again. As we deleted all of the contacts, the query should return zero rows.

    Creating a NHibernate session to access database within ASP.NET

  12. Now, let's create a slightly more complex object and save it to the database. Let's create an OrderHeader with an associated Contact that has an address and associate that Address and the Contact to the OrderHeader:

    Contact ordCntct = new Contact("Martha", "Washington",
    "mw@usa.gov");
    Address ordAddr = new Address("1600 Pennsylvania Ave NW", null,
    "Washington", "DC", "20500");
    ordAddr.Contact = ordCntct;
    ordCntct.Addresses = new List<Address>();
    ordCntct.Addresses.Add(ordAddr);
    OrderHeader header = new OrderHeader();
    header.Number = "0000001";
    header.OrderDate = DateTime.Now;
    header.BillToContact = ordCntct;
    header.BillToAddress = ordAddr;
    header.ShipToContact = ordCntct;
    header.ShipToAddress = ordAddr;
    OrderHeader header = new OrderHeader("00001", DateTime.Now, -1,
    -1, ordCntct, ordCntct, ordAddr, ordAddr);
    session.SaveOrUpdate(header);
    tx.Commit();

    Again, in VB.NET:

    Contact ordCntct = new Contact("Martha", "Washington", _
    "mw@usa.gov");
    Address ordAddr = new Address("1600 Pennsylvania Ave NW", null, _
    "Washington", "DC", "20500");
    ordAddr.Contact = ordCntct;
    ordCntct.Addresses = new List<Address>();
    ordCntct.Addresses.Add(ordAddr);
    OrderHeader header = new OrderHeader();
    header.Number = "0000001";
    header.OrderDate = DateTime.Now;
    header.BillToContact = ordCntct;
    header.BillToAddress = ordAddr;
    header.ShipToContact = ordCntct;
    header.ShipToAddress = ordAddr;
    OrderHeader header = new OrderHeader("00001", DateTime.Now, -1, _
    -1, ordCntct, ordCntct, ordAddr, ordAddr);
    session.SaveOrUpdate(header);
    tx.Commit();

  13. Now let's update our OrderHeader object and set the item quantity to ten items and update it.

    header.ItemQty = 10;
    session.Update(header);
    tx.Commit();

    It's nearly identical in VB.NET:

    header.ItemQty = 10
    session.Update(header)
    tx.Commit()

  14. As we're at it, let's change the order number to "chi3131":

    header.Number = "chi3131";
    session.SaveOrUpdate(header);
    tx.Commit();

    And the VB.NET is the same without the semi-colons:

    header.Number = "chi3131"
    session.SaveOrUpdate(header)
    tx.Commit()

Have a go hero – creating a full order

Now that we know how to create objects and child objects of those objects and so on, let's take it one step further. Create a new OrderHeader object with a billing and shipping Contact with two separate Addresses, namely, one for shipping and one for billing. Create a few OrderItem objects and associate them with the OrderHeader. Save all of these objects to the database, then create an ICriteria and query it back and take a look at the objects that are returned.

Sessions in ASP.NET

Because of the stateless nature of ASP.NET, traditional session management doesn't work so well. If we try to create a single session and use it across several pages or requests, then this statelessness makes it more difficult for us to maintain this than it would in say a Winforms application.

There are a few strategies that we can use to overcome this, including implementing a Singleton pattern, storing the session in the user's Context, or using another framework such as NHibernate.Burrow.

The Singleton is probably the easiest to implement. We simply create a sealed class (meaning all of the member methods and variables are declared static) and create a property called Instance. Then, we create a non-static constructor that has the implementation details we want such as the SessionFactory property.

In C#, this SessionProvider class would look as follows:

public sealed class SessionProvider
{
static readonly SessionProvider instance = new SessionProvider();
public static SessionProvider Instance
{
get
{
return instance;
}
}
public ISessionFactory SessionFactory { get; set; }

public SessionProvider()
{
Configuration cfg = new Configuration();
cfg.Properties.Add(NHibernate.Cfg.Environment.
ConnectionProvider, typeof(NHibernate.Connection
.DriverConnectionProvider).AssemblyQualifiedName);
cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect,
typeof(NHibernate.Dialect.MsSql2008Dialect)
.AssemblyQualifiedName);
cfg.Properties.Add(NHibernate.Cfg.Environment.
ConnectionDriver, typeof(NHibernate.Driver.SqlClientDriver)
.AssemblyQualifiedName);
cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString,
"Server= (local)\\SQLExpress;Database=ordering;
Trusted_Connection=true;");
cfg.Properties.Add(NHibernate.Cfg.Environment.
ProxyFactoryFactoryClass, typeof(NHibernate.ByteCode.LinFu
.ProxyFactoryFactory).AssemblyQualifiedName);
cfg.AddAssembly(typeof(BasicWebApplication.Common
.DataObjects.Address).Assembly);

SessionFactory = cfg.BuildSessionFactory();
}
}

The same factory in VB.NET is just as easy to include:

Public NotInheritable Class SessionProvider
Shared ReadOnly m_instance As New SessionProvider()
Public Shared ReadOnly Property Instance() As SessionProvider
Get
Return m_instance
End Get
End Property

Private _SessionFactory As ISessionFactory
Public Property SessionFactory() As ISessionFactory
Get
Return _SessionFactory
End Get
Set(ByVal value As ISessionFactory)
_SessionFactory = value
End Set
End Property

Public Sub New()
Dim cfg As New Configuration()
cfg.Properties.Add(NHibernate.Cfg.Environment. _
ConnectionProvider,GetType(NHibernate.Connection. _
DriverConnectionProvider).AssemblyQualifiedName)
cfg.Properties.Add(NHibernate.Cfg.Environment.Dialect, _
GetType(NHibernate.Dialect.MsSql2008Dialect). _
AssemblyQualifiedName)
cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionDriver, _
GetType(NHibernate.Driver.SqlClientDriver). _
AssemblyQualifiedName)
cfg.Properties.Add(NHibernate.Cfg.Environment.ConnectionString, _
"Server=(local)\SQLExpress;Database=ordering; _
Trusted_Connection=true;")
cfg.Properties.Add(NHibernate.Cfg.Environment
.ProxyFactoryFactoryClass, GetType(NHibernate.ByteCode.LinFu. _
ProxyFactoryFactory).AssemblyQualifiedName)
cfg.AddAssembly(GetType(BasicWebApplication.Common.DataObjects. _
Address).Assembly)
SessionFactory = cfg.BuildSessionFactory()
End Sub
End Class

Now, to create a session, all we have to do is call as follows:

ISession session = SessionProvider.Instance.SessionFactory.
OpenSession()

Another strategy is to store the session in the Context.Items using the Application_BeginRequest and Application_EndRequest methods in the Global.asax code or in an HTTPModule. I personally don't like these methods as much because it makes the ASP.NET application more difficult to troubleshoot, as you are adding an additional step in the lifecycle of the page.

One of the better frameworks for managing sessions (as well as other items like Units of Work, which we will not talk about here) is NHibernate.Burrow. This framework is part of the NHibernate.Contrib project. You can find out more information about this framework and how to use it at http://nhforge.org/wikis/burrow/home.aspx.

Summary

We covered some great topics in this article that include:

  • What is an NHibernate session?
  • How does it differ from a regular database session?
  • A little about retrieving and committing data
  • Using sessions within ASP.NET

We also touched a little on configuration, caching, and session factories.


If you have read this article you may be interested to view:


NHibernate 2 Beginner's Guide Rapidly retrieve data from your database into .NET objects
Published: May 2010
eBook Price: £16.99
Book Price: £27.99
See more
Select your format and quantity:

About the Author :


Aaron Cure

Aaron Cure is an avid developer, instructor, and innovator. During his 10 years in the military as a linguist and a satellite communications repair technician, he learned that his real love was computer programming.

After various throes with PHP, Classic ASP, VB, and a brief encounter with Java/JSP, he found a real passion for the .NET framework. After searching for a "better way" to carry out database storage and retrieval, Aaron stumbled across the NHibernate framework.

Unsatisfied with the options for interacting with this great framework, he founded the NHibernate Generation project (nhib-gen) on SourceForge to reduce the "barrier to entry" for most developers.

Aaron and his family run a small consulting and web hosting company doing web design and custom software development for various organizations across the country. One of their more interesting projects has been software to control laser cutting machines.

In his spare time, he also enjoys developing projects with his daughters, using everything from Lego NXT (using C# and Bluetooth communications) to the Microchip PIC platform (using JAL and USB). He also collects and restores classic farm tractors, engines, and farm equipment, as well as semi trucks and trailers. He and his family display them at tractor shows, parades, schools, and various other community events.

Books From Packt


Refactoring with Microsoft Visual Studio 2010
Refactoring with Microsoft Visual Studio 2010

Mastering phpMyAdmin 3.1 for Effective MySQL Management
Mastering phpMyAdmin 3.1 for Effective MySQL Management

ASP.NET Data Presentation Controls Essentials
ASP.NET Data Presentation Controls Essentials

Spring Persistence with Hibernate
Spring Persistence with Hibernate

High Availability MySQL Cookbook
High Availability MySQL Cookbook

ASP.NET 3.5 Application Architecture and Design
ASP.NET 3.5 Application Architecture and Design

VSTO 3.0 for Office 2007 Programming
VSTO 3.0 for Office 2007 Programming

C# 2008 and 2005 Threaded Programming: Beginner's Guide
C# 2008 and 2005 Threaded Programming: Beginner's Guide


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software