VB.Net adventures in NHibernate

Photo by Amber Kipp on Unsplash

VB.Net adventures in NHibernate

I’ve listened to the DotNetRocks! episode and watched the DnrTV episode with Oren Eini on NHibernate and I must say NHibernate is both pretty intimidating and mind blowing!

I thought what the heck, I’ll give it a go, best way to learn something new is getting your hands dirty. I was also very interested about how CSLA.Net can fit into NHibernate(But that’s for another time, or my brain will explode)

First, what is NHibernate, well, according to sourceforge Nhibernate is, and I quote:

A .NET port of the excellent Java Hibernate (http://www.hibernate.org)) relational persistence tool.

I recommend listening and watching the 2 shows I’ve mentioned previously, they do help shed some light on Nhibernate.

Go on, I’ll wait for you….

Ok, so you’ve listened and watched the necessary shows, so let’s get started. First you need to download the following(both available from Sourceforge):

  • NHibernate
  • NHibernateContrib

Note: A neat trick I read about here, gives you IntelliSense and validation in the VS.NET XML editor when editing NHibernate mapping and configuration files. I’ve tried integrating the help with VS as described in the same article but could not get it to work with VS2005.

I’ve downloaded the APIDocumentation as well, for good measure. Ok…so let’s get a test scenario. I’ve got an existing database from my client Adventureworks(you can download the sample db from microsoft),which contains all their Customer and Sales data. They want a new interface to this data and they do not want to change the layout of their data. Allrighty.

First we’ll start a new Windows Application VB.net project, named NHibernate_AdventureWorks. Then we’ll add a class for our Customer table, the class will look like this:

.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Public Class Customer

#Region " Members "

Private _CustomerID As Integer = 0
Private _NameStyle As Boolean = False
Private _Title As String = ""
Private _FirstName As String = ""
Private _MiddleName As String = ""
Private _LastName As String = ""
Private _Suffix As String = ""
Private _CompanyName As String = ""
Private _SalesPerson As String = ""
Private _EmailAddress As String = ""
Private _Phone As String = ""
Private _PasswordHash As String = ""
Private _PasswordSalt As String = ""
Private _rowguid As Guid = Nothing
Private _ModifiedDate As Date = Date.Now

#End Region

#Region " Properties "

Public Overridable Property CustomerID() As Integer
    Get
        Return \_CustomerID
    End Get
    Set(ByVal Value As Integer)
        \_CustomerID = Value
    End Set
End Property

Public Overridable Property NameStyle() As Boolean
    Get
        Return \_NameStyle
    End Get
    Set(ByVal Value As Boolean)
        \_NameStyle = Value
    End Set
End Property

Public Overridable Property Title() As String
    Get
        Return \_Title
    End Get
    Set(ByVal Value As String)
        \_Title = Value
    End Set
End Property

Public Overridable Property FirstName() As String
    Get
        Return \_FirstName
    End Get
    Set(ByVal Value As String)
        \_FirstName = Value
    End Set
End Property

Public Overridable Property MiddleName() As String
    Get
        Return \_MiddleName
    End Get
    Set(ByVal Value As String)
        \_MiddleName = Value
    End Set
End Property

Public Overridable Property LastName() As String
    Get
        Return \_LastName
    End Get
    Set(ByVal Value As String)
        \_LastName = Value
    End Set
End Property

Public Overridable Property Suffix() As String
    Get
        Return \_Suffix
    End Get
    Set(ByVal Value As String)
        \_Suffix = Value
    End Set
End Property

Public Overridable Property CompanyName() As String
    Get
        Return \_CompanyName
    End Get
    Set(ByVal Value As String)
        \_CompanyName = Value
    End Set
End Property

Public Overridable Property SalesPerson() As String
    Get
        Return \_SalesPerson
    End Get
    Set(ByVal Value As String)
        \_SalesPerson = Value
    End Set
End Property

Public Overridable Property EmailAddress() As String
    Get
        Return \_EmailAddress
    End Get
    Set(ByVal Value As String)
        \_EmailAddress = Value
    End Set
End Property

Public Overridable Property Phone() As String
    Get
        Return \_Phone
    End Get
    Set(ByVal Value As String)
        \_Phone = Value
    End Set
End Property

Public Overridable Property PasswordHash() As String
    Get
        Return \_PasswordHash
    End Get
    Set(ByVal Value As String)
        \_PasswordHash = Value
    End Set
End Property

Public Overridable Property PasswordSalt() As String
    Get
        Return \_PasswordSalt
    End Get
    Set(ByVal Value As String)
        \_PasswordSalt = Value
    End Set
End Property

Public Overridable Property RowGuid() As Guid
    Get
        Return \_rowguid
    End Get
    Set(ByVal Value As Guid)
        \_rowguid = Value
    End Set
End Property

Public Overridable Property ModifiedDate() As Date
    Get
        Return \_ModifiedDate
    End Get
    Set(ByVal Value As Date)
        \_ModifiedDate = Value
    End Set
End Property

#End Region

End Class

You’ll notice I’ve declared all the properties as Overridable, you’ll thank me later. I then add the following to my app.config file:

With that done, we can set out creating a mapping file for each of our classes. Now you don’t have to create a mapping file for every class, you can combine them, but it’s much cleaner to just create a single mapping file for each class.

I’ve named my mapping file Customer.hbm.xml and it looks like this :

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

The part tells NHibernate that the CustomerID column is an identity column.

As I was typing up the mapping file, one thought immediately sprang to mind: Code Generation!! MyGeneration does have templates for NHibernate, althought I did not check it out yet.

Ok…make sure to change the build action of the mapping file to Embedded Resource. Now before I go on, I had a lot of trouble getting the app.config stuff to work nicely so I deleted the app.config file and created a hibernate.cfg.xml file that looked like this:

<?xml version\='1.0' encoding\='utf-8'?>

NHibernate.Connection.DriverConnectionProvider NHibernate.Driver.SqlClientDriver Server=(local);initial catalog=AdventureWorks; User Id=sa;Password=woozelwazzel

false

NHibernate.Dialect.MsSql2000Dialect

true

I must say I has a world of pain trying to do it the way the quick start guides on the Nhibernate site describes. I cannot tell you. Anyways. The code I used to save a customer to the database looked like this:

Dim myConfig As New Configuration myConfig.SetProperty("hibernate.dialect", _ "NHibernate.Dialect.MsSql2000Dialect") Dim myFactory As ISessionFactory = _ myConfig.Configure.BuildSessionFactory Dim mySession As ISession = myFactory.OpenSession Dim myTransaction As ITransaction = _ mySession.BeginTransaction

Dim myCustomer As New Customer myCustomer.NameStyle = False myCustomer.Title = "Mr." myCustomer.FirstName = "Mythical" myCustomer.MiddleName = "Man" myCustomer.LastName = "Moth" myCustomer.Suffix = "Jr." myCustomer.CompanyName = "Mythical Moth Software Inc." myCustomer.SalesPerson = "adventure-worksjosé1" myCustomer.EmailAddress = "mythicalmanmoth-AT-mmm.net" myCustomer.Phone = "555-TheMoth" myCustomer.PasswordHash = "L@#HGSJFYGSJSDJHISD" myCustomer.PasswordSalt = "jsd67he1/=" myCustomer.RowGuid = New Guid myCustomer.ModifiedDate = Date.Now mySession.Save(myCustomer)

myTransaction.Commit() mySession.Close()

Make sure you add a reference to NHibernate.dll and import both NHibernate and NHibernate.Cfg.

With any luck you’ll see a new customer record in the Customers table. And there you go you’ve got NHibernate to work. I must say, it’s not easy to get going. I’ll post some more intricate examples and scenarios with NHibernate at a later stage.

Until next time keep coding!