Philip Fourie
Philip Fourie

Reputation: 116827

NHibernate mapping multiple relationships

What is the correct HBM mapping for the scenario below?

I need to qualify ValueItem in the database as either an Income or Expense item in order for NHibernate to load it into the correct list when loading it.

The problem is: The contetns of the IncomeItems and ExpenseItems collections are the same when retrieving Container from the DB.

Design

C#

public class Container
{
    public virtual IList<ValueItem> IncomeItems { get; set; }
    public virtual IList<ValueItem> ExpenseItems { get; set; }
}

public class ValueItem
{
    public virtual double Amount { get; set; }
    public virtual string Description { get; set; }
}

HBM

<class name="Container">
    <id name="Id">
        <generator class="hilo" />
    </id>

    <list name="IncomeItems " cascade="all-delete-orphan">
        <key column="ContainerId" />
        <index column="ItemIndex" />
        <one-to-many class="ValueItem"/>
    </list>

    <list name="ExpenseItems " cascade="all-delete-orphan">
        <key column="ContainerId" />
        <index column="ItemIndex" />
        <one-to-many class="ValueItem"/>
    </list> 
</class>


<class name="ValueItem">
    <id column="Id" type="int">
      <generator class="hilo" />
    </id>

    <property name="Amount" />
    <property name="Description" />
</class>    

Upvotes: 1

Views: 472

Answers (2)

Vadim
Vadim

Reputation: 17957

You can either choose an appropriate inheritance strategy: http://nhibernate.info/doc/nh/en/index.html#inheritance

Alternatively, if your schema can't be changed. You can specify where attributes on your list mappings. These will specify how to fetch them.

Upvotes: 0

Philip Fourie
Philip Fourie

Reputation: 116827

This answer from Don on NHUsers solves my problem:

Don's answer:

I have a similar mapping to yours, except that I am using bags instead of lists, I have inverse="true", cascade set to the default, I explicitly set the table name, I have different column names for each key, and I have references back to what would be your Container with unique names for each. Perhaps it's the inverse=true or the different column names.

Sorry about the hokey class names. I changed them from the realdomain object names on the spot, and I'm not feeling very creative. Hope this helps,

<class name="Form" >
    <many-to-one name="CreatorPerson" class="Person" />
    <many-to-one name="ProcessorPerson" class="Person" />
</class>

<class name="Person">
    <bag name="FormsCreated" inverse="true">
        <key>
            <column name="CreatorPersonId" not-null="true" />
        </key>
        <one-to-many class="Person" />
    </bag>
    <bag name="FormsToProcess" inverse="true">
        <key>
            <column name="ProcessorPerson" not-null="true" />
        </key>
        <one-to-many class="Person" />
    </bag>
</class> 

Upvotes: 1

Related Questions