How to map a NHibernate <MAP> tag in FluentNhibernate?

Introduction

One of the common problems experienced when using Fluent NHibernate is how to convert a particular mapping, previously in HBM file format, to a Fluent NHibernate syntax.

In this tutorial example I will model an Entity to Entity-Settings structure. Typically used to stored additional information on the entity when you don’t want to designate a particular column to do the job. So we provide an open structure in the form of a key-value pair table.

In classic NHibernate HBM files you would use a <MAP> element to represent this relationship. However in Fluent NHibernate it’s mapped slightly differently.

Dependencies:

  • NHibernate 3.2.400
  • FluentNHibernate 1.3.0.717

Tutorial:

This is the database structure we will deal with:

I’m intentionally keeping it simple. We have a Customer table that holds basic customer information and a CustomerSettings table which hold key-value pair string information – in other words it holds whatever we want that fits the structure of a key-value pair. I also want any changes to the Customer settings to be saved when I persist the Customer object.

My classes look as follows:

    public class Customer
    {
        public Customer()
        {
            Settings = new Dictionary();
        }

        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Surname { get; set; }
        public virtual IDictionary Settings { get; set; }
    }

The mapping is actually really simple but it took forever to figure out how to do it properly. So the classmap looks like so:

    public class CustomerMap : ClassMap
    {
        public CustomerMap()
        {
            Table("Customer");
            Id(x => x.Id).Not.Nullable().GeneratedBy.Identity();
            Map(x => x.Name).Not.Nullable().Length(50);
            Map(x => x.Surname).Not.Nullable().Length(50);

            HasMany(x => x.Settings)
            .Table("CustomerSettings")
            .KeyColumn("CustomerId")
            .AsMap(
                index => index.Column("`Key`").Type(),
                element => element.Column("Value").Type()
            )
            .Cascade.All();
        }
    }

And that’s it! Now all you need to do is a basic NHibernate save, with your customer information and settings and the settings will also save in your cascade:

            DatabaseContext.Initialize();

            var customer = new Customer
                        {
                            Name    = "Joe",
                            Surname = "Blogs"
                        };
            customer.Settings.Add("Age", "30");
            customer.Settings.Add("Country", "ZA");

            using (var session = DatabaseContext.SessionFactory.OpenSession())
            {
                using (var tx = session.BeginTransaction())
                {
                    session.SaveOrUpdate(customer);
                    tx.Commit();
                }
            }
Advertisements
Explore posts in the same categories: Development, NHibernate

Tags: , ,

You can comment below, or link to this permanent URL from your own site.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s


%d bloggers like this: