Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

many-to-many mapping in NHibernate

I'm looking to create a many to many relationship using NHibernate. I'm not sure how to map these in the XML files. I have not created the classes yet, but they will just be basic POCOs.

Tables

Person
personId
name

Competency
competencyId
title

Person_x_Competency
personId
competencyId

Would I essentially create a List in each POCO for the other class? Then map those somehow using the NHibernate configuration files?

like image 470
Chris Stewart Avatar asked Apr 27 '10 14:04

Chris Stewart


People also ask

What is the difference between NHibernate and fluent NHibernate?

Fluent NHibernate is another way of mapping or you can say it is an alternative to NHibernate's standard XML mapping files. Instead of writing XML (. hbm. xml files) documents.

What is bag in NHibernate?

A bag is an unordered, unindexed collection which may contain the same element multiple times. The . NET collections framework lacks an IBag interface, hence you have to emulate it with an IList. NHibernate lets you map properties of type IList or ICollection with the <bag> element.

What is NHibernate in C #?

NHibernate is a mature, open source object-relational mapper for the . NET framework. It's actively developed, fully featured and used in thousands of successful projects. Easily map regular C# or VB.NET object models designed in Visual Studio.

What is fetch in NHibernate?

A fetching strategy is the strategy NHibernate will use for retrieving associated objects if the application needs to navigate the association. Fetch strategies may be declared in the O/R mapping metadata, or overridden by a particular HQL or Criteria query.


1 Answers

You can put the many-to-many relation to either class, or even to both. This is up to your domain model. If you map it to both, one of them is inverse.

class Person
{
  // id ...
  IList<Competency> Competencies { get; private set; }

  // you domain model is responsible to manage bidirectional dependencies.
  // of course this is not a complete implementation
  public void AddCompetency(Competency competency)
  {
    Competencies.Add(competency);
    competency.AddPerson(this);
  }
}

class Competency
{
  // id ...
  IList<Person> Persons { get; private set; }
}

Mapping:

<class name="Person">
  <id ....>
  <bag name="Competencies" table="Person_x_Competency">
    <key column="personId"/>
    <many-to-many class="Competency" column="competencyId"/>
  </bag>
</class>

<class name="Competency">
  <id ....>
  <bag name="Persons" table="Person_x_Competency" inverse="true">
    <key column="competencyId"/>
    <many-to-many class="Person" column="personId"/>
  </bag>
</class>

Only make it bidirectional if you really need it.

By the way: it is much better to write the classes first and create the database design afterwards. The database can be exported from the mapping files. This is very useful.

like image 146
Stefan Steinegger Avatar answered Oct 13 '22 14:10

Stefan Steinegger