July 28, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Using NHibernate as an ORM Solution for .NET

  • November 6, 2007
  • By David Consdorf
  • Send Email »
  • More Articles »

This example uses the second method, table per subclass. In the database design, you have one class for the Person class and one table for each of the subclasses, Customer and SalesPerson. In the mapping, you see this defined in the joined-subclass tag:

<joined-subclass name="Customer, __Code" table="Customer">
   <key column="PersonID"/>

This tag specifies the Customer class and its associated database table as a subclass of the Person class. The key linking the two rows in each classes table is the PersonID column. Inside the joined-subclass tag, the Customer properties are defined as they normally would be for a class. Note that with this mapping, when NHibernate requests a Customer object from the database, NHibernate will use an SQL join in its query to join the appropriate Person and Customer rows into a complete result for the Customer object.

The next items of interest with this mapping are the collection mappings. Both the Customer class and SalesPerson class have collections mapped, one for orders and the other for assigned customers.

Start with the Orders collection in the Customer class:

<set name="Orders">
   <key column="CustomerID"/>
   <one-to-many class="ProductOrder, __Code"/>
</set>

This is an example of a simple one-to-many relationship. Each order is mapped to one customer and each customer can have several orders. The class associated in this one-to-many relationship is the ProductOrder class that is specified in its own mapping file as being mapped to the ProductOrder database table. The key column for determining this relationship is the CustomerID column in the ProductOrder table.

The next collection mapping example is a bit trickier. Here is the mapping for the AssignedCustomers collection in the SalesPerson class:

<set name="AssignedCustomers" table="AssignedCustomers"
     cascade="save-update">
   <key column="SalesPersonID"/>
   <many-to-many class="Customer, __Code" column="CustomerID"/>
</set>

This is an example of a many-to-many relationship. Each sales person may have several assigned customers and each customer may have several sales persons assigned to them. To handle this sort of relationship, a separate table, AssignedCustomers, is specified in the set tag and is delegated the task of keeping track of which customers are assigned to which sales persons. The key column for the SalesPerson table is the SalesPersonID and the key column for the Customer table is the CustomerID.

The cascade attribute shown here is another topic that will be discussed later.

NHibernate Session Factory and Sessions

Now that everything is set up, you can move into how to utilize NHibernate in the application.

NHibernate works based on session objects. When you need to retrieve, save, update, or delete an object in the database, you create a NHibernate session to perform the task. The session encapsulates all the database functionality and the database connection. Sessions are light-weight and should be created and destroyed as they are needed. They are not thread-safe, so keeping them around and sharing them between threads is not a good idea.

NHibernate sessions are managed by a session factory. Generally, there is one session factory per application. Each time a session is needed, the session factory is called to create one. Session factories are heavy-weight and thread-safe objects that read in all configurations and mappings to configure themselves for an application. Because they take a while to create, they need to be held in memory and shared for an application.

A helper and/or manager class is generally used to help broker the NHibernate session factory's functionality. For this example, I used a standard NHibernateHelper class:

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

   static NHibernateHelper()
   {
      log4net.Config.XmlConfigurator.Configure();

      // Get the mapping file path
      String mappingPath =
         HttpContext.Current.Server.MapPath(
         "/NHibernateExample/App_Code/BusinessObjects/Mappings/");

      // Set up the configuration
      Configuration config = new Configuration()
         .AddFile(mappingPath + "Person.hbm.xml")
         .AddFile(mappingPath + "ProductOrder.hbm.xml");

      // Build the session factory
      sessionFactory = config.BuildSessionFactory();
   }

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

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

      return currentSession;
   }

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

      if (currentSession == null)
      {
         // No current session
         return;
      }

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

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

Listing 5: Sample Application—NHibernateHelper





Page 4 of 6



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel