Как смоделировать Многих ко много-отношениям в коде?

Разделите свое расположение, и Ваше содержание позволяет Вам перепроектировать или делать тонкие настройки и изменения в Вашем сайте легко. Это может взять немного более длинный честный, но самая длинная фаза разработки программного обеспечения является обслуживанием . css дружественный сайт с четким разделением между содержанием и дизайном является лучшим в течение обслуживания.

28
задан John Saunders 19 February 2012 в 00:13
поделиться

12 ответов

Почему вы говорите о таблицах? Вы создаете объектную модель или модель базы данных?

Для объектной модели нет причин, по которым собака не может иметь List , а владелец - List . Только если у вас есть атрибуты в отношении, вам нужен промежуточный класс (который в UML называется классом ассоциации). Вот тогда у вас будет класс DogOwnership с дополнительными свойствами, и каждый владелец будет иметь List , как и каждая собака. Владелец собаки будет иметь собаку, владельца и дополнительные свойства.

25
ответ дан 28 November 2019 в 03:14
поделиться
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.
15
ответ дан 28 November 2019 в 03:14
поделиться

Если вам не нужно записывать псевдоним, тогда у собаки должен быть список боссов, а у босса должен быть список собак.

Если отношения между собакой и боссом имеют атрибуты , в данном случае это псевдоним, тогда вы должны создать класс для представления этих отношений, и пусть Dog и Boss оба содержат списки этого типа.

Я уже некоторое время использую NHibernate и нашел его очень полезно для устранения такого рода несоответствия относительного импеданса объекта .

1
ответ дан 28 November 2019 в 03:14
поделиться

This is a classic issue between databases where many to many doesn't work, hence your helper table, and the object world where many to many works fine. As soon as the relationship has attributes then you should create a new class to hold that information. However, you'll save yourself a lot of head time if you look at Object Relation Mapping - ORM - that whole field grew up to solve this (and many other) problems between DB and Object.

1
ответ дан 28 November 2019 в 03:14
поделиться

Что-то вроде этого; Тем не менее, он все еще нуждается в некоторой доработке (сделайте коллекцию частной и добавьте для нее открытый доступ только для чтения, который, например, возвращает коллекцию только для чтения, но вы уловите дрейф.

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);
        }
    }
}

Таким образом, вы можете смоделировать множество ко многим в вашем коде, где каждая собака знает своих боссов, а каждый босс знает своих собак. Если вам понадобятся дополнительные данные во вспомогательной таблице, вам также потребуется создать другой класс.

7
ответ дан 28 November 2019 в 03:14
поделиться

Если у вас есть простая таблица связывания «многие-ко-многим» с внешними ключами из каждой таблицы во взаимосвязи, вы можете смоделировать ее, как вы предлагаете: у босса есть коллекция собак, а у собаки набор боссов.

Если у вас есть отношение «многие ко многим» с дополнительными данными, такими как псевдоним, то вы можете смоделировать это как два отношения «один ко многим». Создайте объект, например DogBoss, чтобы у Boss была коллекция DogBoss, а у Dog была коллекция DogBoss.

1
ответ дан 28 November 2019 в 03:14
поделиться

традиционное отношение «многие ко многим» не будет иметь дополнительных полей в таблице сопоставления.

Поскольку у вас есть поля с уникальной информацией, я стараюсь перестать думать об этих отношениях как о многих ко многим.

Как только вы добавляете информацию к таблице соответствия, я думаю, вы затем превратили эту таблицу в самостоятельную сущность, и поэтому вам нужен собственный объект для ее представления.

На этом этапе вы можете создать класс DogsName для соединения человека и собаки - оба из них будут содержать ссылки на этот объект как часть коллекции.

Однако не зависит от того, даете ли вы собаке имя, которое она будет называть, или владеете ли собакой.

А также моделирование отношения имени собаки по мнению разных людей, вам также необходимо моделировать отношения собственности. В памяти это будет означать, что оба объекта содержат список других объектов.

2
ответ дан 28 November 2019 в 03:14
поделиться

Думаю, что-то не хватает. Почему не разрешено "многие ко многим"?

public class Boss
{
    Dog[] dogs;
}

public class Dog
{
    Boss[] bosses;
}
0
ответ дан 28 November 2019 в 03:14
поделиться

В реляционной модели лучший способ смоделировать отношения «многие ко многим» (используя ваш пример с собаками / боссами) - иметь три отдельные таблицы.

Одна таблица для DOGS, одна таблица для BOSSES (и каждая из этих таблиц имеет уникальный ключ), а третья таблица обычно представляет собой « соединительную таблицу ».

Эта таблица обычно имеет как минимум два поля, одно поле для внешний ключ для Dog и другое поле для внешнего ключа Boss. Таким образом, у каждой собаки может быть много боссов, а у каждого босса может быть много собак.

Теперь, когда дело доходит до моделирования этого в коде более объектно-ориентированным способом, это обычно достигается за счет наличия класса Dog и босса. класс. Помимо обычных атомарных свойств для каждого из этих объектов, каждый из них будет также выставить свойство, которое является коллекцией другого.

Так, например, объект Dog будет иметь свойство, называемое «Боссы». Это свойство будет предоставлять коллекцию объектов Boss, которые назначены конкретному объекту Dog (как определено в таблице соединений), а с другой стороны, каждый объект Boss будет предоставлять свойство с именем Dogs, которое будет коллекцией выделенных объектов Dog. к этому конкретному объекту Boss (как определено таблицей соединений).

Обратите внимание, что в этих объектах вполне может быть некоторое "перекрытие" (т.е. один объект "собака" может иметь объекты "босса", которые есть у другого объекта "dog" ), однако это традиционный механизм для перевода реляционной модели с тремя таблицами «многие ко многим» в объектно-ориентированную.

0
ответ дан 28 November 2019 в 03:14
поделиться

Не знаю, о чем вы просите. Но это структура таблицы, которую вы хотите:

Dog Table

DOG_ID int PK DOG_Name varchar (50)

DogsPerBoss

ID int DOG_ID int BOSS_ID int DogNickName varchar (15)

Босс

BOSS_ID int PK BOSS_Name varchar (50)

-1
ответ дан 28 November 2019 в 03:14
поделиться

Я что-то упускаю или это единственный код, который вам нужен для этого, например:

List<Bosses> BossList;

class Dog {}
class Boss { Dog[] Dogs; }

Вам не нужно явно моделировать двусторонние отношения. Это неявно присутствует в структуре кода. Для этого могут быть и другие причины, но в целом достаточно иметь одностороннюю ссылку и способ обхода набора ссылающихся объектов.

0
ответ дан 28 November 2019 в 03:14
поделиться

Множественное назначение реализуется как комбинация упаковки кортежа и распаковки кортежа, насколько мне известно, поэтому оно должно иметь одинаковый эффект.

-121--3460735-

Как уже упомянули несколько человек, приложение Apple Intro to Memory Management на сегодняшний день является лучшим местом для начала.

Одной из полезных ссылок, которую я еще не видел, является Практическое управление памятью . Вы найдете его в середине документов Apple, если вы читаете через них, но это стоит прямой ссылки. Это блестящее резюме правил управления памятью с примерами и распространенными ошибками (в основном, какие другие ответы здесь пытаются объяснить, но не так хорошо).

-121--2512014-

Каждый раз нам нужно думать о реальной жизни и наших потребностях. В этом случае ключевым пунктом является то, какой из них должен быть другим.

В реальной жизни собака и босс могут не иметь друг друга. Но ваши потребности в программном обеспечении должны повлиять на эти отношения.

  • Например, если вы разрабатываете программное обеспечение для управления пациентами ветеринара, для ветеринара, который лечит бездомных собак, отношения Пациент (собака) - Guardian (босс) должны быть такими: Боссы должны иметь, по крайней мере, одну собаку, и собака может не иметь какого-либо босса (тогда boss id является внешним ключом этих отношений), что означает, что в вашем дизайне класс собаки должен держать коллекцию боссов. Почему, потому что любой экземпляр босса не может быть создан без собак. Мы также можем принять это решение с помощью логики данных. Давайте подумаем о том, когда вы пытаетесь сохранить свои занятия с собакой и боссом в базе данных. Если условие связи, как указано выше, при сохранении бобышки следует вставить запись соединения в таблицу соединений.

  • Если вы разрабатываете это программное обеспечение для ветеринара, который не лечит бездомных собак, то отношения Пациент - Родитель должны быть такими: Собака должна иметь хотя бы одного босса, а босс должен иметь хотя бы собаку, и нам нужно рассмотреть этот особый случай отношений. Это означает, что любой из этих экземпляров классов не может быть создан без других. Таким образом, мы должны определить эту специализацию в нашем дизайне OO. Это означает, что нам нужен класс, который представляет эту зависимость. Эта зависимость будет сохранена в таблице соединений.

- Если ваше программное обеспечение разработано для ветеринара, который лечит бездомных собак и этих собак, принятых боссами, ваш дизайн должен быть таким: Любая собака может не иметь босса (боссов), и любой босс может не иметь любого пса (псов) до усыновления. В этом случае наш проектировать OO должен заботиться об этом особом случае. Этот случай немного похож на первый. Так что мы можем добавить коллекцию любого класса в другой. Но любые потребности в программном обеспечении, подобные этому, повлияют на другие потребности. Как отчетность. Если ветеринар беспокоится о собаках, которых усыновил босс (и), рано или поздно он просит сообщить, какую собаку перенял кто. Как и в предложении, (собаки, принятые боссом (ами)) лучше, если собачий класс содержит коллекцию классов босса.

Надеюсь, я смогу дать правильные ответы на ваш вопрос.

0
ответ дан 28 November 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: