Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to model a Many to many-relationship in code?

Suppose I have 2 tables in a database. eg: Dog & Boss This is a many to many relationship, cause a boss can have more than 1 dog, and a dog can have more than 1 owner. I am the owner of Bobby, but so is my wife.

But many to many is not allowed, so there is a helpertable: DogsPerBoss

How to model this in code?

Class Boss can have a collection of Dogs. Class Dog can have a collection of Bosses. --> at least, that is what I think. Perhaps there are better solutions?

How about extra data that is in the helper-table? Should that be in de Boss-class or in the Dog-class? eg: Nickname (I call the dog "good boy" and my wife calls him "doggie")

I hope my question is kinda clear? Are there any best-practices on what is the best way to achieve this? Can you give me some references?

An ORM (like NHibernate) is not an option.

like image 585
Natrium Avatar asked Jul 09 '09 12:07

Natrium


People also ask

How do you implement many-to-many relationship in code?

The many-to-may relationship can be achieved using HasMany and WithMany methods. The default conventions for many-to-many relationships creates a joining table with the default naming conventions. You can customize a joining table name and column names using Fluent API.

How do you model a many-to-many relationship?

When you have a many-to-many relationship between dimension-type tables, we provide the following guidance: Add each many-to-many related entity as a model table, ensuring it has a unique identifier (ID) column. Add a bridging table to store associated entities. Create one-to-many relationships between the three tables.

How do you create a many-to-many relationship in SQL?

When you need to establish a many-to-many relationship between two or more tables, the simplest way is to use a Junction Table. A Junction table in a database, also referred to as a Bridge table or Associative Table, bridges the tables together by referencing the primary keys of each data table.


2 Answers

Why are you talking about tables? Are you creating an object model or a database model?

For an object model, there's no reason a Dog can't have a List<Owner> and an owner have a List<Dog>. Only if you have attributes on the relationship do you need an intermediate class (what UML calls an Association Class). That's when you'd have a DogOwnership class with extra properties, and each Owner would have a List<DogOwnership>, and so would each Dog. The DogOwner would have a Dog, an Owner, and the extra properties.

like image 65
John Saunders Avatar answered Sep 21 '22 00:09

John Saunders


public class Boss {    private string name;    private List<Hashtable> dogs;    private int limit;     public Boss(string name, int dogLimit)    {       this.name = name;       this.dogs = new List<Hashtable>();       this.limit = dogLimit;     }     public string Name { get { return this.name; } }     public void AddDog(string nickname, Dog dog)    {       if (!this.dogs.Contains(nickname) && !this.dogs.Count == limit)       {          this.dogs.Add(nickname, dog);          dog.AddBoss(this);       }     }     public void RemoveDog(string nickname)    {        this.dogs.Remove(nickname);        dog.RemoveBoss(this);    }     public void Hashtable Dogs { get { return this.dogs; } } }  public class Dog {    private string name;    private List<Boss> bosses;     public Dog(string name)    {       this.name = name;       this.bosses = new List<Boss>();    }     public string Name { get { return this.name; } }     public void AddBoss(Boss boss)    {       if (!this.bosses.Contains(boss))       {           this.bosses.Add(boss);       }    }     public void RemoveBoss(Boss boss)    {       this.bosses.Remove(boss);    }       public ReadOnlyCollection<Boss> Bosses { get { return new ReadOnlyCollection<Boss>(this.bosses); } } } 

The above maintains the relationship of Bosses can have multiple dogs (with a limit applied) and dogs having multiple bosses. It also means that when a boss is adding a dog, they can specify a nickname for the dog which is unique to that boss only. Which means other bosses can add the same dog, but with different nicknames.

As for the limit, I would probably have this as an App.Config value which you just read in before instantiating the boss object(s). So a small example would be:

var james = new Boss("James", ConfigurationManager.AppSettings["DogsPerBoss"]); var joe = new Boss("Joe", ConfigurationManager.AppSettings["DogsPerBoss"]);  var benji = new Dog("Benji"); var pooch = new Dog("Pooch");  james.AddDog("Good boy", benji); joe.AddDog("Doggy", benji);  james.AddDog("Rover", pooch); joe.AddDog("Buddy", pooch);  // won't add as the preset limit has been reached. 

You can obviously tweak this as you see fit, however, I think the fundamentals of what you are looking for are there.

  • Boss can have multiple dogs with limit
  • Dogs can have multiple bosses
  • Bosses can have different nicknames for same dog.
like image 37
James Avatar answered Sep 19 '22 00:09

James