NHibernateComplex relationships

time to read 3 min | 541 words

Originally posted at 11/18/2010

I got an interesting question today (I am teaching my NHibernate course now).

The tabular structure is similar to this:

image

But the desired object structure is:

image

That is quite different than the tabular model, but it is actually very easy to handle this with NHibernate.

Here are the mapping for the Address entity. We use the <join/> tag to have an entity that spans more than a single table:

<class name="Address"
       table="Addresses">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="City" />

  <join table="PeopleAddresses" >
    <key column="AddressId"/>
    <property name="IsDefault"/>
    <property name="ValidFrom"/>
    <property name="ValidTo"/>
  </join>

</class>

We then map the Person, using standard many-to-many mapping for the addresses:

 <class name="Person"
             table="People">

   <id name="Id">
     <generator class="identity"/>
   </id>
   <property name="Name" />

   <bag name="Addresses" table="PeopleAddresses" inverse="true">
     <key column="PersonId"/>
     <many-to-many class="Address" column="AddressId"/>
   </bag>
   
 </class>

There is just one thing thing to be aware of, you can’t add new addresses via the Person.Addresses collection, because the PeopleAddresses table has more data in it than just the keys. Presumably, you are handling this in some other fashion already.

All in all, this is a pretty elegant solution.

More posts in "NHibernate" series:

  1. (19 Nov 2010) Complex relationships
  2. (27 Jun 2010) Streaming large result sets
  3. (25 May 2009) Why do we need to specify the query type twice?
  4. (20 Mar 2009) Avoid identity generator when possible
  5. (26 Mar 2007) Nullable DateTime Issues
  6. (08 Jan 2007) Fetching multiply collections in one roundtrip