Search code examples
c#nhibernatenhibernate-mappingone-to-many

Mapping two bidirectional collections of the same type in Nhibernate


I have a model like this

public class Scene
{
    public virtual ICollection<Ray> Rays1 {get; set;}
    public virtual ICollection<Ray> Rays2 {get; set;}
}

public class Ray
{
    public virtual Scene Parent {get; set;}
}

If I keep it this way and map it with 2 one-to-many relationships this is happening:

  • Create a Scene
  • Add 3 items on Rays1
  • Add 2 items on Rays2
  • Commit to database
  • Query scene from database

Now both Rays1 and Rays2 have 5 elements, because they share the same parent id

The only solution I could think of is to inherit 2 new classes from Ray and then map each of them with one-to-many relationships. This will create two separate tables on database, but they'll have exactly the same columns. It just doesn't feel right to me...

Is there any other solutions available?

--edit--

For reference, here are my mapping files:

  <?xml version="1.0" encoding="utf-8" ?>
  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                      assembly="PanoMeasurer.Core.Domain" 
                      namespace="PanoMeasurer.Core.Domain">
    <class name="Panorama">

      <id name="OID" generator="guid.comb"/>

      <property name="HeadingBase"/>

      <set name="Rays1" cascade="all-delete-orphan">
        <key column="PanoramaId" />
        <one-to-many class="Ray"/>
      </set>

      <set name="Rays2" cascade="all-delete-orphan">
        <key column="PanoramaId" />
        <one-to-many class="Ray"/>
      </set>
    </class>

  </hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="PanoMeasurer.Core.Domain" 
                   namespace="PanoMeasurer.Core.Domain">
  <class name="Ray">
    <id name="OID" generator="guid.comb"/>
    <property name="Heading"/>
    <property name="Elevation"/>
    <many-to-one name="Owner" class="Panorama" column="PanoramaId" />
  </class>
</hibernate-mapping>

Solution

  • If you choose to go with a single mapping, then you can make the Rays1 and Rays2 as filters on a Rays list.

    public virtual ICollection Rays1 { return Rays.Where()};