2009-04-22 55 views
6

我正在一個小型教育項目上鍛鍊perst.net。C中的多對象到對象的關係#

我們有一個微小的設計問題,那就是如何以最佳方式解決兩類對象之間的關係,那就是參與者冠軍。這是一個多對多的關係作爲參與者可以參加很多冠軍冠軍可以有多個參與者

請告知如何在C#中做到最好,我應該使用'關係數據庫'技術類嗎?

回答

1

我不知道這是否適用於你的設計或要求,但有可能...

顯然,一個多到多的關係是最容易與管理的關係的第三個目的是代表。在你的情況下,這將是一個冠軍參賽者。而不是在你的參加者班上有一個擁有冠軍的集合,反之亦然,讓他們舉辦這個第三班的實例。對象管理這種關係。然後它可以作爲聯結表直接序列化到數據庫。

4

您可以使用IEnumerable(或其他集合)屬性在特定項目可以有多個項目關聯的任何關係。在你的榜樣,這將如下所示:

class Participant { 
    public IEnumerable<Championship> Championships { 
     get { 
     return _championships; 
     } 
    } 
    private List<Championship> _championships; 
} 

要記住一些重要的事情:

  • 務必使這是一個只讀屬性。這有時會讓人感到困惑,特別是如果你有一些可修改的內容像返回的ICollection而不是IEnumerable。使屬性爲只讀不會阻止對集合進行修改,但對整個列表進行修改。

  • 加載策略 - 在上面的示例中,您會注意到集合未初始化。您通常在構造函數中或者第一次訪問屬性(稱爲延遲實例化)時執行此操作 - 通常而言,延遲實例化會增加一些複雜性,但可以提高性能,特別是如果此集合不經常使用,或者您有很多類型的屬性。

  • 通常,在多對多(即參與者擁有錦標賽屬性但冠軍不具有參與者屬性或反之亦然)的情況下選擇一個類別來「保留」其他類別是個好主意。這減少了您必須編寫的代碼量,並降低了數據庫的複雜性和表面積。如果另一個方向需要調用,請考慮方法調用而不是屬性。請記住,關係意義上的多對多並不一定意味着這是常見用例(作爲用戶,我可能只想將參與者添加到錦標賽而不是參加者的錦標賽)

  • 如果您的集合是請記住,發送Save意味着它下面的集合也應該被修改,如果它們被更改了。這會增加複雜性的一個很好的協議(在過去,我已經用內部列表存儲添加/刪除的項目)

+0

哇。偉大的anwser。 – 2009-04-22 11:18:35

8

如果你正在尋找一個面向對象的(或領域驅動設計)方式則處理「連接」的第三個對象完全是錯誤的方式。您可以使用ILists /可枚舉與添加...方法來處理這個如下:

public class Participant 
{ 
    private readonly IList<Championship> _championships = new List<Championship>(); 

    public IEnumerable<Championship> Championships 
    { 
     get { return _championships; } 
    } 

    internal void AddChampionship(Championship championship) 
    { 
     if (!_championships.Contains(championship)) 
      _championships.Add(championship); 
    } 
} 

public class Championship 
{ 
    private readonly IList<Participant> _participants = new List<Participant>(); 

    public IEnumerable<Participant> Participants 
    { 
     get { return _participants; } 
    } 

    public void AddParticipant(Participant participant) 
    { 
     if (_participants.Contains(participant)) return; 
     _participants.Add(participant); 
     participant.AddChampionship(this); 
    } 
} 

這裏的關鍵是要確保你管理從一個側面唯一的關係 - 例如在這種情況下,這將通過調用championship.AddParticipant()

+1

很好的回答!最後的聲明是至關重要的......你應該讓它大膽面對! +1 – Cerebrus 2009-04-22 11:51:27