对象/实体:多对多+多对一

时间:2010-01-29 15:47:39

标签: c# entity-relationship entities

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

首先,这会将标记对象添加到标记列表中。然后该标记对象将“this”产品添加到它自己的产品列表中。

到目前为止一切顺利。

但是,如果我想将产品添加到标签,该怎么办?我的

中有这样的方法

标记实体:

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

首先,我将产品对象添加到我的标记对象中的产品列表中。然后,我可以将“this”标签添加到产品中,但这是我遇到的问题。被注释的方法会抛出stackoverflow错误,因为它会调用AddProduct调用AddTag,依此类推等等。

不确定我的架构是否也非常正确。当我想看到用户拥有的标签时,从用户到标签的M-T-O就可以轻松实现。

所以我想知道是否有人能指出我正确的方向?

提前致谢,

Pickels

4 个答案:

答案 0 :(得分:1)

向产品添加标签对我来说更有意义。我不允许将产品添加到标签中。

通过多对多关系,您需要确定哪个实体是关系中的主要实体,并通过它控制对集合的访问。您可以通过将另一个实体上的Add方法标记为内部来控制访问。

标记实体:

internal virtual void AddProduct(Product product)
{
    this.Products.Add(product);
}

答案 1 :(得分:0)

不要使用MTM关系man,而应该创建一个只有2列的新表Products_Tags:ProductID和TagID。这两个外键都是这样的:

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

答案 2 :(得分:0)

检查列表是否已包含此元素是一种很好的做法。

if ( !this.Tags.Contains(tag) ) 
{ 
 this.Tags.Add(tag);
 product.AddTag(this);
}

答案 3 :(得分:0)

Tag.AddProduct应仅添加到代码的内部产品列表中,而Product.AddTag应仅添加到产品的内部代码列表中。持久化到DB应该处理交叉映射 - 当您保存每个产品时,映射表应该在映射表中保存一行,并且当您保存每个标记时相同。

在域中维护这个逻辑对我来说没有意义,我也看不到任何真正的好处。产品有许多标签,标签有很多产品 - 这应该是域的结构,持久层负责多对多关系。

这样,对于任何你知道它有什么标签的产品,反之亦然,这是你真正需要知道的。

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