Lesser-Known NHibernate Features: Dynamic Components

NHibernate, unlike others, has lots of ways to map columns from the database to and from classes. Normally, there is a 1:1 relation between columns and properties, but it doesn’t have to be so: there are, for example, components and dynamic components.

This time we will be looking at dynamic components. Dynamic components allow the usage of a dictionary, where one or several columns from the database will be stored, each in its own entry. This is pretty cool, if we need to add more columns at some point, and we do not want, or can, change the class!

Show me the code, I hear you say:

public class DataStore
{
    public DataStore()
    {
        this.Data = new Dictionary<String, Object>();
    }
 
    public virtual int Id { get; set; }
 
    public virtual IDictionary Data { get; set; }
}

Yes, it will be possible to use generic dictionaries (IDictionary<TKey, TValue>), when pull request for NH-3670 is merged, which should happen soon (NHibernate 4.1).

Now, the mappings:

var mapper = new ConventionModelMapper();
mapper.Class<DataStore>(x =>
    {
        x.Id(y => y.Id, y => { });
        x.Component(y => y.Data, new
        {
            A = 0,
            B = ""
        }, y =>
        {
            y.Property(z => z.A);
            y.Property(z => z.B);
        });
    });

I am setting the template for whatever will be stored in the Data dictionary, in this case, an integer column (A) and a string one (B) as an anonymous object. In NHibernate 4.1, it will be possible to use a dictionary instead (see NH-3704), which will help in making it more dynamic. In the third parameter to Component, we can change the mapping, for example, the physical properties of each column; we can even use ManyToOne instead of Property, so that a particular entry in the dictionary will point to another entity!

A sample usage:

session.Save(new DataStore { Data = new Dictionary<String, Object> { { "A", 1 }, { "B", "two" } } });

                             

1 Comment

Add a Comment

As it will appear on the website

Not displayed

Your website