Episerver and NHibernate

NHibernate has been used for many years as an ORM tool for C# applications.  In the same line as LINQ to SQL, Entity Framework, and others, ORM tools remove most of the need to write stored procedures to handle common data access (CRUD) for your business objects. Episerver has its own implementation named Dynamic Data Store (DDS).

DDS is useful if you work with small among of data, but I experienced performance issues with thousands of records. As an alternative, you can migrate to NHibernate to have a more maintainable project.

This tutorial takes advantage of the Sharp Architecture project which already implements NHibernate.

Install Sharp Architecture in Episerver Projects

Install the SharpArch.NHibernate nuget package which includes NHibernate and FluentNHibernate libraries.

Install-Package SharpArch.NHibernate

Initialize NHibernate through an initialization module:

using System.Reflection;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using SharpArch.Domain.PersistenceSupport;
using SharpArch.NHibernate;

namespace Alloy_NHibernateTest.NHibernate
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class NHibernateInitialization : IConfigurableModule
    {
        public void Initialize(InitializationEngine context)
        {           
        }

        public void Uninitialize(InitializationEngine context)
        {
        }

        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            var container = context.StructureMap();

            var session = Fluently.Configure()
                .Database(
                    MsSqlConfiguration.MsSql2012
                        .ConnectionString(
                            cs => cs.FromConnectionStringWithKey
                                ("EPiServerDB"))
                )
                .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()))
                .BuildSessionFactory().OpenSession();


            container.Configure(c =>
            {
                c.For(typeof(ILinqRepository<>))
                    .Use(typeof(LinqRepository<>));

                c.For<INHibernateTransactionManager>()
                    .Use<TransactionManager>()
                    .Ctor<ISession>("session").Is(session);
            });
        }
    }
}

The code above initializes Nhibernate using the database EPiServerDB which is defined in the connectionstring section. Additionally, we are registering the class ILinqRepository that is implemented by SharpArch, and it will be used to execute CRUD operations.

Now, you have to create your domain objects and map them using Fluent NHibernate. The following example shows how to map the table tblSiteDefinition. Remember this is just an example, and you should not manipulate Episerver tables directly.

using SharpArch.Domain.DomainModel;

namespace Alloy_NHibernateTest.NHibernate
{
    public class Site : Entity
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string SiteUrl { get; set; }
    }
}

Mapping class:

using FluentNHibernate.Mapping;

namespace Alloy_NHibernateTest.NHibernate
{
    public class SiteMap : ClassMap<Site>
    {
        public SiteMap()
        {
            Table("tblSiteDefinition");

            Id(x => x.Id).Column("pkID");

            Map(x => x.Name).Column("Name")
                .Not.Update()
                .Not.Insert();

            Map(x => x.SiteUrl).Column("SiteUrl")
                .Not.Update()
                .Not.Insert();
        }
    }
}

One of the great things about Sharp Architecture is that it has created a generic repository for you. Generally there’s no need to worry about the NHibernate session, or creating a specific repository each time you need to talk to your database. As such, let’s create a local field and inject it into our controller or business class:

protected readonly ILinqRepository<Site> _siteRepository;

public StartPageController(ILinqRepository<Site> siteRepository)
{
   _siteRepository = siteRepository;
}

Return all records:

var sites = _siteRepository.GetAll();

Return a single object:

var page = _siteRepository.Get(1);

Save an object:

_siteRepository.SaveOrUpdate(page);

Delete an object

_siteRepository.Delete(page);

We’ve achieved the basics of a CRUD operation using NHibernate in your Episerver projects.

One thought on “Episerver and NHibernate

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s