1
          用户
      / \  
     / \
  MTO MTO
   / \  
  / \
产品----MTM----标签

我想知道是否有任何关于如何使用实体创建这样的模式的文档。我一直想知道哪个实体应该对关系中的什么负责。

例如:

假设我想为产品添加标签。我有这样的方法

产品实体:

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

所以首先我将产品对象添加到我的标签对象中的产品列表中。然后我可以将“this”标签添加到产品中,但这就是我卡住的地方。被注释的方法会引发 stackoverflow 错误,因为它会回调调用 AddTag 的 AddProduct 等等。

也不确定我的架构是否真的正确。当我想查看用户拥有哪些标签时,从用户到标签的 MTO 让我很容易。

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

提前致谢,

泡菜

4

4 回答 4

1

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

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

标记实体:

internal virtual void AddProduct(Product product)
{
    this.Products.Add(product);
}
于 2010-01-29T16:10:59.233 回答
0

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

          Users
      /           \  
     /             \ 
  M-T-O           M-T-O 
   /                 \  
  /                   \
Products              Tags
  \                    /
   \                  /
    \                /
     \               /
      \Products_Tags/
于 2010-01-29T16:01:33.483 回答
0

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

if ( !this.Tags.Contains(tag) ) 
{ 
 this.Tags.Add(tag);
 product.AddTag(this);
}
于 2010-01-29T16:16:11.593 回答
0

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

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

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

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);
}
于 2010-01-29T16:47:30.173 回答