I have read a post on the internet (I can no longer find that post for me to refeence) that a Many-To-Many relationship can be replaced with a one-to-many relationship. Can someone provide an example?
-
Please describe your tables and what classes you want to use. – cremor Mar 20 '13 at 07:26
-
3As relational DBMSs typically don't support many-to-many relationships, those relationships are represented using a linking table and two one-to-many relationships. For example, a many-to-many relationship between `User`s and `Role`s is expressed as `User one-to-many UserRoles many-to-one Role`. NHibernate usually hides this and allows many-to-many relationshops transparently. If you want, you can always choose to map the linking table explicitly, ie. you'd map `User`, `Role` _and_ `UserRoles`, where `UserRoles` contains two many-to-one relationships (to a `User` and a `Role` respectively). – Andre Loker Mar 20 '13 at 08:40
-
(cont'd). In this case neither `User` nor `Role` would need to hold collections (one-to-many) of `UserRoles` instances (or at least they can be inverse). This can be useful to reduce the memory footprint because you need to load fewer collections into memory. The downside is that queries become more complex. – Andre Loker Mar 20 '13 at 08:44
-
@cremor I've asked my question out of pure curiosity. I currently don't have a problem with a set of tables/classes – burnt1ce Mar 20 '13 at 14:11
-
@Andrew Loker: Thank you for the explaination. can you provide a link to a webpage that contains sample code supplementing your explanation? – burnt1ce Mar 20 '13 at 14:13
-
Just a reminder, you really should accept the answer below by @Radim Köhler, it does address your question. – mcfea Mar 09 '15 at 15:41
1 Answers
I just come up to that question, and realized, that there is missing any answer. And it is a shame, while I do often point out this NHibernate documentation statement: 24. Best Practices
Don't use exotic association mappings.
Good usecases for a real many-to-many associations are rare. Most of the time you need additional information stored in the "link table". In this case, it is much better to use two one-to-many associations to an intermediate link class. In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary.
Take a look at the example under the 23.2. Author/Work. Extract, the simplified version of the many-to-many relation between Author
and Work
:
<class name="Work" table="works" ...>
<id name="Id" column="id" generator="native" />
...
<set name="Authors" table="author_work" lazy="true">
<key>
<column name="work_id" not-null="true"/>
</key>
<many-to-many class="Author">
<column name="author_id" not-null="true"/>
</many-to-many>
</set>
</class>
And its many-to-many target Author:
<class name="Author" table="authors">
...
<set name="Works" table="author_work" inverse="true" lazy="true">
<key column="author_id"/>
<many-to-many class="Work" column="work_id"/>
</set>
</class>
So, if we would like to order the set of Works on load, we do have a problem. There is no column in the pair table. But what's more important, there is no way how to manage such a column.
What we can do, is to introduced the Pair object: AuthorWork
and extend the Pair table as needed
public class AuthorWork
{
public virtual Author Author { get; set; }
public virtual Work Work { get; set; }
public virtual int OrderBy { get; set; }
}
Mapping of the AuthorWork
<class name="AuthorWork" table="author_work">
...
<many-to-one name="Author" column="author_id" />
<many-to-one name="Workr" column="work_id" />
<property name="OrderBy" />
Having this we can convert the many-to-many mapping to one-to-many, for example the Authors collection:
<set name="Authors" lazy="true"
order-by="OrderBy">
<key column="work_id" not-null="true"/>
<one-to-many class="AuthorWork" />
</set>
And we can manage the entity AuthorWork, set the OrderBy column, and therefore effectively work with the pairing table.
NOTE: have to agree with that suggestion in docsumentation The more requirements come, the more happy we are that we do have a way how to manage the relation!

- 3,559
- 4
- 25
- 46

- 122,561
- 47
- 239
- 335
-
5Heads up the best practices link has moved to: http://nhibernate.info/doc/nh/en/index.html#example-mappings-authorwork – mcfea Mar 09 '15 at 20:28