Объекты / объекты: многие ко многим + многие к одному - PullRequest
1 голос
/ 29 января 2010
          Users
      /           \  
     /             \ 
  M-T-O           M-T-O 
   /                 \  
  /                   \
Products----M-T-M----Tags

Интересно, есть ли документация о том, как создать такую ​​схему с сущностями. Я застрял в размышлении о том, какая сущность должна нести ответственность за что в отношениях.

Например:

Допустим, я хочу добавить метку к товару. У меня есть такой метод в моем

сущность продукта:

    public virtual void AddTag(Tag tag)
    {
        this.Tags.Add(tag); // IList<Tag> Tags
        tag.AddProduct(this);
    }

Сначала добавляется объект тега в список тегов. Затем этот объект тега добавляет этот продукт в свой список продуктов.

Пока все хорошо.

Но что, если я хочу добавить товар в тег? У меня есть такой метод в моем

тег сущности:

    public virtual void AddProduct(Product product)
    {
        this.Products.Add(product); // IList<Product> Products
        // product.AddTag(this);
    }

Итак, сначала я добавляю объект product в список продуктов в моем объекте tag. Затем я мог бы добавить тег «this» к продукту, но именно здесь я застрял. Комментируемый метод генерирует ошибку stackoverflow, поскольку он вызывает метод AddProduct, который вызывает AddTag и т. Д. И т.

Не уверен, что моя схема действительно верна. M-T-O от пользователя к тегам облегчает задачу, когда я хочу увидеть, какие теги есть у пользователя.

Так что мне было интересно, кто-нибудь может указать мне правильное направление?

Заранее спасибо,

Pickels

Ответы [ 4 ]

1 голос
/ 29 января 2010

Для меня гораздо больше смысла добавлять тег к продукту. Я бы не позволил добавить товар в тег.

При наличии отношений «многие ко многим» вам необходимо решить, какая сущность является основной сущностью в отношениях, и контролировать доступ к коллекции через нее. Вы можете контролировать доступ, пометив метод Add для другого объекта как внутренний.

Тэг объекта:

internal virtual void AddProduct(Product product)
{
    this.Products.Add(product);
}
0 голосов
/ 29 января 2010

Tag.AddProduct следует добавлять только во внутренний список продуктов тега, а Product.AddTag следует добавлять только во внутренний список тегов Product. Сохранение в БД должно обрабатывать перекрестное сопоставление - при сохранении каждого продукта в таблице сопоставления должна быть строка, сохраненная в таблице сопоставления, и при сохранении каждого тега одинаковым.

Сохранение этой логики в области не имеет смысла для меня, и я не вижу никаких реальных преимуществ. У продукта есть много тегов, а у тега есть много продуктов - это должно быть, как структура домена, с постоянным уровнем, заботящимся об отношениях «многие ко многим».

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

class Users
{
  private Tags tags;
  private Products products;
}

class Tags : IList<Tag> {}
class Tag
{
  private Products products;
  public void AddProduct(Product product);
}

class Products : IList<Product> {}
class Product
{
  private Tags tags;
  public void AddTag(Tag tag);
}
0 голосов
/ 29 января 2010

Рекомендуется проверить, содержит ли список этот элемент.

if ( !this.Tags.Contains(tag) ) 
{ 
 this.Tags.Add(tag);
 product.AddTag(this);
}
0 голосов
/ 29 января 2010

Не используйте MTM Relationship Man, вместо этого вы должны создать новую таблицу Products_Tags только с 2 столбцами: ProductID и TagID. оба внешних ключа вроде этого:

          Users
      /           \  
     /             \ 
  M-T-O           M-T-O 
   /                 \  
  /                   \
Products              Tags
  \                    /
   \                  /
    \                /
     \               /
      \Products_Tags/
...