Search code examples
asp.net-mvcinheritancenhibernatemappingnhibernate-mapping

NHibernate mapping class with attribute of same type


I am new to the .NET MVC. However this "problem" I am stuck at looks pretty common, I cannot find any tutorial or stackoverflow thread that explains how to do it properly.

I have a class, MyClass which has two attributes of same type

 public class MyClass : IEquatable<MyClass>
 {
     public virtual MyClass LeftChild { get; set; }
     public virtual MyClass RightChild { get; set; }
     ...
 }

Now I have problem with nhibernate mapping. At first I tried one-to-one mapping. I created new instance and DO NOT set Childs , persisted it (lets say Id=1), and pass this instance to View and I expected that RightChild will be NULL and LeftChild will be NULL. But in the debbug mode i can see, that the RightChild was set to MyClass with Id=1 (Like MyClass instance set itself to this attribute) and same with LeftChild.

Mapping MyClass.hbm.xml

...    
<one-to-one name="LeftChild" class="MyClass"/>
<one-to-one name="RightChild" class="MyClass"/>
...

Is it right approach to do it with one-to-one or I should use something else ?


Solution

  • References, where our table contains foreign keys, are almost always best to map with many-to-one.

    Simply think about it as a standard reference to other instance (Country, Currency)... which is accidentally of a same type.

    <many-to-one name="LeftChild"  column="LeftChild_ID"  class="MyClass"/>
    <many-to-one name="RightChild" column="RightChild_ID" class="MyClass"/>
    

    The only challenge I see, is to be sure that the server part (C# code, app) will be properly setting these values. There is not bi-directional mapping in this kind of persisted information. Each sibling, needs its own information who is right who is left.

    I mean, comparing with Similar mapping: parent-child (also same type). In that case we would have child having reference to parent, and parent having collection of children.

    But that is not the same here.. again.. we map just one side of the relation.

    A one-to-one is not suitable here, because it requires two tables, with (almost) the same amount of rows, sharing same column as a key... I like to use it, but for kind of Additional info... see: