views:

117

answers:

2

Is there a way to map a many-to-many relationship with properties on each item in the list specific to the relationship? The actual case I'm trying to solve is this:

A business can be related to many contacts, and a contact can be related to many businesses. What I want to do is provide a status for the relationship, like active or deleted and a date the contact was invited (or added) to be a contact for that business. So say a contact can be active for one business, but pending for another business.

I know I can easily achieve this by just making the relationship an actual entity and mapping the association entity to the collections, but I REALLY hate doing that. It just feels dirty making something like a relationship an actual entity. What I'm wondering is if there's a way to map the relationship specific properties to each object. So, say I have the list of contacts for a business. Each contact in that list would have a status, but in the mapping it would make that status specific to the business. I was hoping I could do something like this in what would be the business mapping:

<bag name="Contacts" table="BusinessContactAssociations" lazy="true" cascade="all">
  <key column="BusinessID"/>
  <many-to-many class="Contact" column="ContactID">
    <join table="BusinessContactAssociations">
      <key column="ContactID"/>
      <property name="InvitedDate"/>
      <property name="Status"/>
    </join>
  </many-to-many>
</bag>

but of course that doesn't work, because join can't be used within a many-to-many, but it illustrates what I want.

Anyone have any handy nhibernate mapping magic for me?

A: 

As far as I know many-to-many is only used for using a typical two column join table. Given that you want to add properties to the relationship you would be better off mapping it as two separate one-to-many relationships with a join class (well it's more than that because it has its own properties but you know what I mean).

Update

This isn't nHibernate magic but there's nothing to stop you from using a join class that is private or otherwise hidden and then exposing the properties of the join class from your main classes.

Michael Gattuso
I ended up doing it the way I really didn't want to by making the association an entity and then using a one-to-many on each side as you had described above. If I didn't absolutely despise the use of maps, I might have looked into that suggestion, but using strings for property names when I have a well defined set of properties doesn't fly with me.
Mitch
A: 

You can use <map> to get ternary associations instead of your <many-to-many> mapping. You can then use <composite-index> to get value objects used as the key of the dictionary, if you want more than one property associate with the relationship. Check out Ayende's blog post for some example code.

John Rayner