2010-01-29 201 views
1
 
      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); 
    } 

首先,我的產品對象添加到產品列表中我的標籤對象。然後,我可以將「this」標籤添加到產品中,但這是我卡住的地方。被評論的方法會拋出一個stackoverflow錯誤,因爲它會調用AddProduct來調用AddTag,等等。

不確定我的模式是否真的正確。從用戶到標籤的M-T-O可以讓我們輕鬆查看用戶擁有的標籤。

所以我想知道是否有人能指引我進入正確的方向?

由於提前,

Pickels

回答

1

對我來說,添加標籤到產品上更有意義。我不會允許產品添加到標籤。

通過多對多關係,您需要決定哪個實體是關係中的主要實體,並通過它控制對集合的訪問。您可以通過將另一個實體的Add方法標記爲內部來控制訪問。

標籤實體:

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

不要使用MTM關係的人,而不是這個,你應該創建只有2列的新表Products_Tags:產品ID和標籤識別。這兩個外鍵是這樣的:

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

我認爲他們低估了你,因爲我談論的是實體而不是任何數據庫模式。在我的數據庫中,我將有一個ProductsTags表。 – Pickels 2010-01-29 16:11:52

+0

問題是如何建模域模型中的多對多關係,而不是數據庫中。 – 2010-01-29 16:13:04

0

這是一個很好的做法,以檢查是否已經列表包含此元素。

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

使用Contains時是否需要關注性能? – Pickels 2010-01-29 16:30:23

+0

一個調用默認實現.Contains =整個列表中的一個循環。 – ikhaldeev 2010-01-29 16:46:36

+0

With包含您必須關心引用相等性:「此方法使用默認相等比較器EqualityComparer <(Of <(T>)>).. ::。T的默認值,列表中值的類型。」 – 2010-01-30 15:04:37

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

我對此非常不滿,保持關係的雙方保持內存中的對象一致。遵循這一邏輯,您必須堅持並檢索您的產品和標記對象以使其集合包含預期的對象。 – 2010-01-29 17:17:56

+0

但是肯定依賴於系統的體系結構,因爲內存中的對象可能與給定M2M關係的數據庫不同步,所以負載可能會謹慎以避免假設內存中狀態與數據庫的內存狀態相匹配? – 2010-01-31 01:47:27