views:

19

answers:

1

I have three classes mapped using the table-per-subclass class mapping strategy. The tables are:

  • Images - ImageId, FileName, ImageData
  • CategoryImages - CategoryId, ImageId
  • ProductImages - ProductId, ImageId

We are mapping like so:

<class name="CatalogImage" table="Images">
<id name="Id" column="ImageId">
  <generator class="guid.comb"/>
</id>
<property name="FileName"/>
<property name="ImageData" lazy="true"/>

<joined-subclass name="CategoryImage" table="CategoryImages">
  <key column="ImageId"/>
  <many-to-one name="Category" column="CategoryId"/>
</joined-subclass>
<joined-subclass name="ProductImage" table="ProductImages">
  <key column="ImageId"/>
  <many-to-one name="Product" column="ProductId"/>
</joined-subclass>

I am able to save instances of Image, CatalogImage and ProductImage.

However, the main reason for composing the image types in this way is so that I have one central image gallery from which I can grab images and attach them to a product, category etc.

This is the part I am struggling with. How can I retrieve an instance of Image and use it to create an instance of ProductImage and upon saving, add the reference to the ProductImage table.

I tried a basic cast (ProductImage)normalImage but this failed as I'm using a dynamic proxy.

Thanks, Ben

+1  A: 

You are misusing inheritance. The relationship between a Product/Category and an Image is not "is-a" but "has-a" or "has-many" (composition).

So, if a Product has many images, with your current database structure you can just map a collection of Images in product; ProductImage is not a class.

Example:

class Product
{
    public virtual ICollection<Image> Images { get; set; }
}

Mapping:

<class name"Product">
  ...
  <set name="Images" table="ProductImages">
    <key column="ProductId"/>
    <many-to-many column="ImageId" class="Image"/>
  </set>
</class>

You can also map two inverse collections of Categories and Products in Image, to see what elements it has been attached to.

Diego Mijelshon
@Diego, what if I want to specify a different display order for product images and category images. Can I still achieve this with your example above?
Ben
Think I have answered my own question. I can use a list for this and specify the index column.
Ben
That's correct. You just have to change `<set>` to `<list>`, `ICollection` to `IList`, and add the `<index column="..."/>`
Diego Mijelshon