views:

262

answers:

2

Hi all,

I have a file attachment class (FileAttachment) which is used in several other classes.

e.g. An article contains multiple attachments. A category contains multiple attachments. These attachments are actually the same FileAttachment class but for obvious reason they are persisted in different tables. e.g. file attachment for an article in Article_FileAttachments table and category file attachments in a Category_FileAttachments table.

How can i represent this relationship in the nhibernate mappings? thx

A: 

Some options here - I don't know which one will work best for you:

  1. You may be able to use the <any> mapping to do what you want. More info at the NHForge docs and from Ayende. I haven't used this myself, so I'm not entirely sure it will help.
  2. Create ArticleAttachment and CategoryAttachment classes which both derive from FileAttachment. These class can be mapped normally and NHib does not need to be specially told about the base class. The problem here is that you will not be able to map a collection that contains both ArticleAttachments and CategoryAttachments.
  3. Have a single FileAttachment table which stores details of all attachments. These can then be linked to your Article and Category table using a <many-to-many> join.
John Rayner
could you explain the 3rd option in a bit more detail please? thx
Yannis
Table ArticleAttachment: columns ArticleID, FileAttachmentIDTable CategoryAttachment: columns CategoryID, FileAttachmentIDTable FileAttachment: columns ID, Name, etcYour Article and Category mappings should then include something like:<set name="FileAttachments"> <key column="ArticleID" /> <many-to-many column="FileAttachmentID" class="FileAttachment" /></set>
John Rayner
A: 

Please see Chapter 8 for polymorphic mapping rules with NHibernate.

In short, you will need a discriminator column to specify what discriminator persists to what table. Here's an instance from the NHibernate documentation, OR if you use inheritance, you will only need to map your derived classes as subclasses and specify the datatable name for each of them from within your base type class mapping.

<class name="IPayment" table="PAYMENT">
  <id name="Id" type="Int64" column="PAYMENT_ID">
    <generator class="native"/>
  </id>
  <property name="Amount" column="AMOUNT"/>
  ...
  <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
    <key column="PAYMENT_ID"/>
    ...
  </joined-subclass>
  <joined-subclass name="CashPayment" table="CASH_PAYMENT">
    <key column="PAYMENT_ID"/>
    ...
  </joined-subclass>
  <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
    <key column="PAYMENT_ID"/>
    ...
  </joined-subclass>
</class>

You may observe that a Payment is a payment, whatever its type of payment. So, it is mapped as a IPayment. Then, subcategorized in multiple tables which represents each type of payment by its discriminator column.

Chapter 8 - Polymorphic mapping

Will Marcouiller