tags:

views:

191

answers:

1

I have an existing POCO class library where children collections are all stored in arrays. For instance, the Customer class has a Invoice[] array to hold its invoices:

class Customer
{
    public int ID;
    public Invoice[] _invoices;
}

class Invoice
{
    public int ID;
    public int CustomerID;
    public string SomeData;
}

I cannot change those classes and I want to map them to an existing database using NHibernate.

I looked at the <array> mapping but it seem to require an <index> element. In my database, the [Invoice] table does not have an index column. When Invoices of a Customer are loaded, I don't expect them to be at any specific position in the array.

What are my options?

+1  A: 

Unfortunately, your options are to change either your class or your table.

A) You can change Customer to declare invoices as IList instead of array; you will then be able to map them as unsorted bag. You can even make it sorted by some column:

<bag name="Invoices" table="Invoices" order-by="ID ASC"> <!-- order-by is optional -->
  <key column="CustomerID"/>
  <element column="SomeData" type="String"/>
  <!-- or use one-to-many if Invoice is mapped as entity -->
  <one-to-many class="Whatever.Invoice, Whatever"/>
</bag>

B). You can change your table to contain an index column and map your invoices as real <array>:

<array name="Invoices" table="Invoices" order-by="ID ASC"> <!-- order-by is optional -->
  <key column="CustomerID"/>
  <index column="IndexNr"/>
  <element column="SomeData" type="String"/>
</array>
ChssPly76
@ChssPly76: This is a pretty big project so I'm willing to invest quite a bit of time to achieve that without changing the classes nor the database. What if I'm willing to extend NHibernate and provide my own implementation of the Array mapping? Is that simple (I'm totally new to NHibernate so I have no idea of what's involved)? Can I subclass the default Array mapping an produce a sequential index value on the fly and in-memory only? Maybe I should discuss that on the NH mailing list...
Sly
You certainly can implement your own collection type; you'll need to implement `IUserCollectionType` in order to do so and reference your class name via `collection-type` attribute in mapping. Here's an article on the topic: http://www.javalobby.org/java/forums/m91832311.html; it deals with Hibernate / java but pretty much everything should be directly portable over to NHibernate as well.
ChssPly76
@ChssPly76: Thanks for the pointers. I checked the `IUserCollectionType`, the `ArrayType` and the `PersistentArrayHolder` classes. It seems like I can subclass `ArrayType` without too much difficulty.
Sly