0

I have many to many relationship.

Table A, Table B and table AB. Table AB will include 2 columns, A_Id and B_id.. The primary key need to be from the both of the column.

Many B records can refer to one A record. But for each record in B only one A record is mutch

What is right syntax in the HBM and the POCO class?

Thank in advance

Shir
  • 253
  • 1
  • 6
  • 18
  • you can declare the ID from multiple cols, using CompositeId (example: http://www.codeproject.com/Tips/419780/NHibernate-Mappings-for-Composite-Keys-with-Associ) – flo scheiwiller Apr 29 '14 at 12:34
  • I don't want to use composite id for A table. because I use the Id for other tables relationship. – Shir Apr 29 '14 at 13:22

1 Answers1

0

This is an example based on the pretty clear example in documentation: 23.2. Author/Work

<class name="A" table="A" >

    <id name="Id" column="A_Id" generator="native" />

    <bag name="Bs" table="AB" lazy="true">
        <key column="A_Id">
        <many-to-many class="B" column="B_Id" not-null="true" />
    </bag>
    ...
</class>


<class name="B" table="B" >

    <id name="Id" column="B_Id" generator="native" />

    <bag name="As" table="AB" lazy="true" inverse="true">
        <key column="B_Id">
        <many-to-many class="A" column="A_Id" not-null="true" />
    </bag>
    ...
</class>

And this would be the classes in C#

public class A 
{
   public virtual int Id { get; set; }
   public virtual IList<B> Bs { get; set; }
}

public class B 
{
   public virtual int Id { get; set; }
   public virtual IList<A> As { get; set; }
}

The table AB is here implicitly mapped ... no explicit pairing object AB

But my own prefered way is to Extend table AB with AB_ID surrogated key, and map it as a standard object. If you like read more about explicit pairing object as a mapped Entity:

UPDATE related to the comment that B can have only one A

In that case, we do not need the AB table. The B should have the column A_Id, expressing the rela reference:

<class name="A" table="A" >

    <id name="Id" column="A_Id" generator="native" />

    <bag name="Bs" table="B" lazy="true">
        <key column="A_Id">
        <!-- not MANY but ONE-TO-Many -->
        <one-to-many class="B" />
    </bag>
    ...
</class>


<class name="B" table="B" >

    <id name="Id" column="B_Id" generator="native" />

    <many-to-one name="A" column="A_Id" />
    ...
</class>

The entities

// This class is the same
public class A 
{
   public virtual int Id { get; set; }
   public virtual IList<B> Bs { get; set; }
}
// here just a reference
public class B 
{
   public virtual int Id { get; set; }
   public virtual A A { get; set; }
}

The thing is, either it is many-to-many and the table AB is in place - or not. Nothing in between I'd say

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thank you. Maybe I was not clear enough. A is not many to many. A can have many B record refer to one A record. But for each record in B only one A record is mutch. Sorry for my mistake. What is now the right syntax ? Thank you – Shir Apr 29 '14 at 13:15
  • Well the point then is, that we will **not** need (remove) the table `AB`. Then B table will have `A_Id` column and the mapping will be similar for A but B will use ` – Radim Köhler Apr 29 '14 at 13:36
  • I understand your solution. but the requirement is to have AB Table although we can do like your suggestion. So what I need to do? Thank you. – Shir Apr 29 '14 at 13:47
  • I would definitely perfer to use the `A_Id` column as a part of the table `B`. This is the real and very well working solution `many-to-one` and `one-to-many`. (see my updated answer) I do use this approach only. Almost nothing else (no many-to-many). With this approach you can do nice projections and searching. See my updated answer, there is a draft of that mapping. If you really need table AB ... the many-to-many is the most reasonable option (while some can say that we can use ) Check it here: http://nhforge.org/doc/nh/en/index.html#mapping-declaration-join – Radim Köhler Apr 29 '14 at 13:53