{STATIC} hippo

...on becoming a great developer...
posts - 38, comments - 12, trackbacks - 0

My Links

Archives

Post Categories

NHibernate Generic Dictionary Mapping

"NHibernate: have I told you today how much I love you?"

The other day I had a good reason to use a generic dictionary and I though hey, I wonder how I'll get that working with NHibernate...  It's very simple to persist Generic Dictionarys with NHibernate as I found out.  Let's see an example...

.NET PSEUDO CODE

Take a person and his favorite or least favorite deserts:

First we have a Person object

class Person
-----------
int PersonId
string FirstName
string LastName

And a desert object

class Desert
------------
int DesertId
string Name

Now we want to associate a Person with all the deserts and rate how much he likes them (I know, it's contrived, but it's simpler than the business case I did this with yesterday).  So first we might create an enum for storing how one feels about a particular dessert (we'll call it Rating):

enum Rating
-----------------------
Love,
Like,
Impartial,
Dislike,
Disdain

And then we might add a generic dictionary to the Person object like so:

class Person
-----------
string FirstName
string LastName
Dictionary<Desert, Rating> DesertRatings

Looks good.  Now how would we use NHibernate to persist this?  First off, let's make a slight change to the Person object because NHibernate actually uses IDictionary, so that last line of the Person object would look more like:

IDictionary<Desert, Rating> DesertRatings

DATABASE TABLES

To persist this data we first create the tables in our database.  Assuming we used the code above, I would probably create 3 different tables: 1 to store the Persons, 1 to store Deserts, and 1 to store the association between Persons and their Desert ratings.  The tables might look like this:

PEOPLE
PersonId, int
FirstName, varchar
LastName, varchar

DESERTS
DesertId, int
Name, varchar

PEOPLEDESERTRATINGS  (PersonId and DesertId will be the primary keys since 1 person can only have 1 rating for a specific desert)
PersonId, int
DesertId, int
Rating, int (this will store the integer representation of the enum)

NHibernate Mappings

Now behold the magic of NHibernate.  Let's take a look at what the Person.hbm.xml file might look like:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyAssembly" namespace=MyNamespace">
<class name="Person" table="People">
<id name="PersonId" column="PersonId" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>
<property name="FirstName" column="FirstName" type="String" not-null="true" />
<property name="LastName" column="LastName" type="String" not-null="true" />
<map name="DesertRatings" table="PeopleDesertRatings">
<key column="PersonId" />
<index-many-to-many class="Desert" column="DesertId" />
<element column="Rating" type="MyNamespace.Rating" not-null="true" />
</map>

</class>
</hibernate-mapping>

That's all there is too it.  There's a lot that I didn't cover here, and this is NOT meant to be a tutorial on how to design your objects or tables.  However, I think I've shown how amazingly easy it is to persist this kind of thing using NHibernate.  I didn't find anything online about this before I tried it and it worked the first time, but I would have felt more comfortable trying it had I seen someone else do it first.  So hopefully this post helps someone feel comfortable diving right in.

Print | posted on Wednesday, January 14, 2009 4:42 PM | Filed Under [ NHibernate ]

Feedback

Gravatar

# re: NHibernate Generic Dictionary Mapping

I just ran across this post – has helped me a lot.

I am struggeling with the challenge to have a Dictionary(string,Ratins), i.e. indexed by dessert name rather than by Dessert objects. It seems that most suggestions assume that the dessert name is pulled into the ranking table.
I would like to keep the Dessert table and reference it from the Ranking table – mainly because replicating the dessert names would be a giant overhead (think about 5 desserts, but thousands of persons/rankings).

Anyone has an idea?
4/30/2010 9:27 AM | Juanita

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 6 and 3 and type the answer here:

Powered by:
Powered By Subtext Powered By ASP.NET