如何在代码中建模多对多关系?

Nat*_*ium 28 c# modeling many-to-many

假设我在数据库中有2个表.例如:Dog&Boss这是一个多对多的关系,因为老板可以拥有超过1只狗,而一只狗可以有超过1只拥有者.我是Bobby的老板,但我的妻子也是.

但是很多人不被允许,所以有一个很好的帮助:DogsPerBoss

如何在代码中对此进行建模?

班老板可以拥有一系列狗.Class Dog可以拥有一系列老板. - >至少,这就是我的想法.也许有更好的解决方案?

辅助表中的额外数据怎么样?应该是de Boss级还是Dog级?例如:昵称(我叫狗"好孩子",我的妻子叫他"小狗")

我希望我的问题有点清楚吗?有什么最好的方法来实现这个目标是什么?你能给我一些参考吗?

ORM(如NHibernate)不是一个选项.

Joh*_*ers 25

你为什么要谈论桌子?您在创建对象模型还是数据库模型?

对于对象模型,没有理由狗不能拥有List<Owner>和拥有者拥有List<Dog>.只有在关系上有属性时才需要中间类(UML称为关联类).那就是当你有一个具有额外属性的DogOwnership类时,每个所有者都会拥有一个List<DogOwnership>,每个Dog 都会有.DogOwner将拥有狗,所有者和额外的财产.


Jam*_*mes 15

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); } }
}
Run Code Online (Sandbox Code Playgroud)

以上保持了老板的关系可以有多只狗(限制适用)和狗有多个老板.这也意味着当老板添加狗时,他们可以为狗指定一个昵称,该昵称仅对该老板是唯一的.这意味着其他老板可以添加相同的狗,但具有不同的昵称.

至于限制,我可能会将此作为App.Config值,您在实例化boss对象之前就读过它.所以一个小例子是:

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.
Run Code Online (Sandbox Code Playgroud)

你可以在你认为合适的情况下调整它,但是,我认为你所寻找的基本原理是存在的.

  • 老板可以有多只限量的狗
  • 狗可以有多个老板
  • 老板可以为同一只狗提供不同的昵称.


Fre*_*els 7

像这样的东西; 它仍然需要一些微调(使集合私有,并为它添加一个只读公共访问器,例如返回readonlycollection,但你会发现漂移.

public class Dog
{
    public List<Boss> Bosses;

    public void AddBoss( Boss b )  
    {
        if( b != null && Bosses.Contains (b) == false )
        {
            Bosses.Add (b);
            b.AddDog (this);
        }
    }

    public void RemoveBoss( Boss b )
    {
         if( b !=null && Bosses.Contains (b) )
         {
             Bosses.Remove (b);
             b.RemoveDog (this);
         }
    }
}

public class Boss
{
    public List<Dog> Dogs;

    public void AddDog( Dog d )
    {
         if( d != null && Dogs.Contains (d) == false )
         {
              Dogs.Add(d);
              d.AddBoss(this);
         }
    }

    public void RemoveDog( Dog d )
    {
        if( d != null && Dogs.Contains(d) )
        {
            Dogs.Remove (d);
            d.RemoveBoss(this);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以在代码中对多对多进行建模,其中每只狗都知道他的老板,并且每个Boss都知道他的狗.当您需要辅助表中的额外数据时,您还需要创建另一个类.

  • +1以补偿"无理由"downvote (2认同)