views:

84

answers:

1

I have an object that maintains a property bag of various properties. This is exposed through my object model as a Dictionary<string, string> and is stored in the database as a JSON-encoded string.

What is the best way to map this class using Fluent NHibernate?

Option 1: Map to a private field, do JSON translation in my object?

Should I map the property to a private string field, and then do serialization to/from JSON in my object itself?

Pro: NH need only know about mapping a single string to a text column which seems easy enough.

Con: My model has to track the dictionary and a string, simply to support persistence.

Option 2: Use some sort of Interceptor?

I haven't done anything with NH Interceptors before, but I know of them. Could I use an interceptor to do the Dictionary/JSON serialization, so that my model need only know about the dictionary?

Option 3: Use a different encoding strategy?

Is there a different encoding strategy, besides JSON, that NH supports natively and that I could use to serialize my dictionary?

+1  A: 

In order to store your Dictionary as a single encoded column, use a IUserType. You would map the dictionary as a property using your IUserType. This blog post has a good example of implementing an IUserType.

Map( x => x.JsonDictionary )
    .CustomTypeIs<MyUserType>();

You can also map this as a collection of values. This allows querying of individual values from the dictionary.

HasMany( x => x.JsonDictionary )
    .WithTableName("entity_jsondictionary")
    .KeyColumnNames.Add("entityid")
    .Cascade.All()
    .AsMap<string>(
        index => index.WithColumn("name").WithType<string>(),
        element => element.WithColumn("value").WithType<string>()
    );
Lachlan Roche
@Lachlan: I have no need to query on individual properties, so it seems better to just store them in a single text field. Would you create a name/values table even if the pairs would never be referenced except as part of this property bag?
Seth Petry-Johnson
@Lachlan: I think CustomType might work. According to (http://stackoverflow.com/questions/242022/nhibernate-mapping-to-custom-types), looks like I just need to create a `JsonEncodedDictionary` class with a few special methods... I like this approach, since it keeps the serialization code away from the domain object. Thanks!
Seth Petry-Johnson
@Seth if you have no need for queries on individual name/value then the encoded column is what you want.
Lachlan Roche