Barbaros Alp
Barbaros Alp

Reputation: 6434

How to map Items which its SubItems are in the same Table with Nhibernate?

I am trying to build a messaging system and for this i have the table definition below

Message

Id
From
To
Body
ParentId // Subcollection, i want to get Asnwers (Message.ParentId== Message.Id)
IsRead

and i have this in the Message.cs

IList<Message> Answers;

I have tried this but it gives me all the messages and all the answers in the main collection.

But i dont want answers to be seen like a message (like the main item).

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="RealEstate.Core" namespace="RealEstate.Core.Domain">
  <class name="Message" table="Message" lazy="true">
    <id column="id" type="Int64" name="Id">
      <generator class="native" />
    </id>
    <property name="From" column="[From]" type="Int64" />
    <property name="To" column="[To]" type="Int64" />
    <property name="Body" column="Body" />
    <property name="ParentId" column="ParentId" type="Int64" />
    <property name="SenderType" column="SenderType" type="Byte" />
    <property name="IsRead" column="IsRead" type="Boolean" />

    <bag name="Answers" lazy="true" cascade="delete">
      <key column="ParentId" />
      <one-to-many class="Message"/>
    </bag>

  </class>
</hibernate-mapping>

How can this mapping be done, they are in the same table ?

Thank you very much

Upvotes: 0

Views: 294

Answers (2)

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

You want to map a tree ? Maybe this could help: how to map a tree in nhibernate

Upvotes: 0

tobinharris
tobinharris

Reputation: 2559

Before attempting an answer, I'd strongly recommend that you search the NHibernate Users Group as there are tons of helpful NHibernate folks that lurk there answering all kinds of questions.

But let me see if I can help here.

Hmmm, I'm not totally sure I understand the question. You say:

I have tried this but it gives me all the messages and all the answers in the main collection.

But i dont want answers to be seen like a message (like the main item).

Do you mean that the Answers collection contains all answers in the database?

Can you post up more code, showing the query your running, and the class code?

One potential problem you have with your scenario is that ParentId can be NULL in the database. This gives NHibernate problems when mapping a one-to-many.

Try making the association bidirectional (documentation reference). That sometimes helps avoid a few traps.

To do that, add this to your class

public class Message {
  ///<summary>Reference to parent message</summary>
  public Message Parent {get;set;}

  //... rest of class

Add this to your mapping:

<bag name="Answers" lazy="true" cascade="delete" inverse="true">
   <key column="ParentId" />
   <one-to-many class="Message"/>
</bag>

<many-to-one name="Parent"/> 

The inverse=true will make NHibernate manage the relationship from the Parent property, not the collection. This is necessary because ParentId can be null.

In your code, rather than using myMessage.Answers.Add( blah ); you can use answer.Parent = myMessage. Of course, you can write nice helper methods to make this more meaningful.

someMessage.AddAnswer( someAnswer );

Which looks like this:

public void AddAnswer(Message answer)
{
   answer.Parent = this;  
   if( ! this.Answers.Contains(answer) )
      this.Answers.Add(answer);
}

Hope this helps.

Upvotes: 1

Related Questions