Introduction
| This article is about using the OR-Mapper NHibernate which is mapping a data representation from an object model to a relational data model in a .NET-environment. The article contains the main steps to get started with NHibernate by a short example-project. It is the first part of a planned series of NHibernate-tutorials. |
Getting started
First of all you need to download NHibernate from
www.sourceforge.net/nibernate
In the example I used Nhibernate 1.0.4. After unzipping you will find the Assemblies NHibernate.dll and log4net.dll. These you'll have to reference in your VS-Project. In our example we will create an ASP.NET-Application with C# in VS 2005 and MSSql-Server 2000.
After creating the Project/WebSite and referencing the Assemblies mentioned above, the configuration-part will follow.
www.sourceforge.net/nibernate
In the example I used Nhibernate 1.0.4. After unzipping you will find the Assemblies NHibernate.dll and log4net.dll. These you'll have to reference in your VS-Project. In our example we will create an ASP.NET-Application with C# in VS 2005 and MSSql-Server 2000.
After creating the Project/WebSite and referencing the Assemblies mentioned above, the configuration-part will follow.
Configuration
In this step you have to tell NHibernate where to find your datastore and which kind of database you use. Add the configuration to your Web.config-File like in this sample configuration for MSSql2000-Server. In the connect_string-property add your database and hostname.
<configSections> <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" /> configSections> <nhibernate> <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" /> <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" /> <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" /> <add key="hibernate.connection.connection_string" value="User ID=sa;Password=admin;Data Source=MyServer;Initial Catalog=MyDB"/> nhibernate>
To access the database with NHibernate we need an NHibernate-Session-object. In an ASP.NET-application we want one session per Request. How can this be achieved? ASP.NET offers a nice feature for this: IHttpModules. You have to implement the interface IHttpModule to use the methods BeginRequest and EndRequest. In the beginning of a request you open the session and when the request ends you close it:
////// NHibernateHttpModule /// public class NHibernateHttpModule : IHttpModule { public const string KEY = "_TheSession_"; private static ISession _session; private void context_BeginRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; context.Items[KEY] = SessionHelper.OpenSession(); } private void context_EndRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; HttpContext context = application.Context; ISession session = context.Items[KEY] as ISession; if (session != null) { try { session.Flush(); session.Close(); } catch {} } context.Items[KEY] = null; } public static ISession CurrentSession { get { if (HttpContext.Current == null) { if (_session != null) return _session; _session = SessionHelper.OpenSession(); return _session; } else { HttpContext currentContext = HttpContext.Current; ISession session = currentContext.Items[KEY] as ISession; if (session == null) { session = SessionHelper.OpenSession(); currentContext.Items[KEY] = session; } return session; } } } }
The class SessionHelper is an own implementation you can find in the attached project. You can use the class NHibernateHttpModule to obtain your session object which you need to create queries or run inserts, updates or deletes in the database. Examples on how to do this will be shown later in this article.
What's the mapping...?
NHibernate maps between .NET-Classes (Objects) and relational data (Database-Tables). These mappings are defined in XML-Documents.
Add a new dll for your domain-objects to the solution and name it NHibernateASPSample.Domain. After that add an XML-File to this project and name it like {MyTableName}.hbm.xml. In the example we will use the file DbUser.hbm.xml that maps to a class and Db-table named DbUser.
Note: In the properties for the file set the Build action to Embedded resource:
Add a new dll for your domain-objects to the solution and name it NHibernateASPSample.Domain. After that add an XML-File to this project and name it like {MyTableName}.hbm.xml. In the example we will use the file DbUser.hbm.xml that maps to a class and Db-table named DbUser.
Note: In the properties for the file set the Build action to Embedded resource:
xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="NHibernateASPSample.Domain" assembly="NHibernateASPSample.Domain"> <class name="DbUser" table="DbUser"> <id name="IdUser" column="IdUser" type="Int32"> <generator class="identity"/> id> <property name="Login" column="Login" type="String"/> <property name="Password" column="Password" type="String"/> <property name="UserData" column="UserData" type="String"/> class> hibernate-mapping>
The class DbUser that corresponds to that declaration looks like this:
namespace NHibernateASPSample.Domain { ////// Class that holds the data of the table DbUser /// public class DbUser { #region Members private int _idUser; private string _login; private string _password; private string _userData; #endregion ////// A standard-constructor is needed! /// public DbUser() { } public int IdUser { get { return _idUser; } set { _idUser = value; } } public string Login { get { return _login; } set { _login = value; } } public string Password { get { return _password; } set { _password = value; } } public string UserData { get { return _userData; } set { _userData = value; } } } }
The properties in your class have to match the properties you defined in your configuration.
The table DbUser in the database contains the following fields:
The table DbUser in the database contains the following fields:
Figure 1
Now the mapping is done. We have finished the requirements to do database operations with the class DbUser. But how can we do it? The next section will enlight this.
Accessing the data
The architecture of NHibernate provides several interfaces for managing your defined Object-Model. To access the database through your objects, you need an ISession-Instance from an ISessionFactory. We already have got an access to an ISession-instance that we defined in our IHttpModule. In the following example we will create a new DbUser and store it to the database. You don't need to write any SQL for that:
// Get the Session from NHibernateHttpModule ISession session = NHibernateHttpModule.CurrentSession;
Now you are able to load, save, update or delete data using your declared classes and the ISession-Instance from NHibernate. In the following example we will create a new DbUser and store it to the database. You don't need to write any SQL for that:
// Creating a new user and save it to database DbUser user = new DbUser(); user.Name = "Codegod"; user.Password = "secret"; user.UserData = "Some other data"; session.Save( user ); // Get a user from database by the user's id DbUser theUser = session.Load( typeof( DbUser ), 1 );
Isn't it easy. There are a lot of other useful methods:
// If the Id of the Object is not defined, the Object is saved. // Otherwise the data is updated in the database. session.SaveOrUpdate( user ); // Update the new data user.Name = "NewName"; session.Update( user ); // Delete the Object from database session.Delete( user );
Well, this was a short introduction to NHibernate and ASP.NET for getting you started with this framework. A sample project is attached that demonstrates how to setup an ASP.NET-project to use NHibernate. In the next part of this article I will talk about:
Have fun!
- Mapping sublasses and collections
- Transactions with NHibernate
- Querying data
Have fun!