C# C语言中的多对多对象关系#

C# C语言中的多对多对象关系#,c#,.net,oop,object-oriented-database,C#,.net,Oop,Object Oriented Database,我正在做一个小的教育项目来锻炼perst.net 我们有一个很小的设计问题,那就是如何最好地解决两类对象之间的关系,即参与者和冠军。这是一种多对多关系,因为参与者可以参加多个锦标赛,锦标赛可以有多个参与者 请建议如何在C#中做到最好,我是否应该使用“类似关系数据库”的技术类?我不确定这是否适合您的设计或要求,但可能 显然,多对多关系最容易用管理该关系的第三个对象表示。在你的情况下,这将是一个冠军的参与者。不要在你的参与者类中有一个拥有锦标赛的集合,反之亦然,让他们拥有第三个类的实例。Champi

我正在做一个小的教育项目来锻炼perst.net

我们有一个很小的设计问题,那就是如何最好地解决两类对象之间的关系,即参与者和冠军。这是一种多对多关系,因为参与者可以参加多个锦标赛,锦标赛可以有多个参与者


请建议如何在C#中做到最好,我是否应该使用“类似关系数据库”的技术类?

我不确定这是否适合您的设计或要求,但可能


显然,多对多关系最容易用管理该关系的第三个对象表示。在你的情况下,这将是一个冠军的参与者。不要在你的参与者类中有一个拥有锦标赛的集合,反之亦然,让他们拥有第三个类的实例。ChampionShippParticipant对象管理此关系。然后可以将其作为连接表直接序列化到数据库。

您可以使用IEnumerable(或某些其他集合)属性建立任何关系,其中特定项可以有多个与之关联的项。在您的示例中,如下所示:

class Participant {
   public IEnumerable<Championship> Championships { 
      get {
         return _championships;
      }
   }
   private List<Championship> _championships;
}
课堂参与者{
公共数字锦标赛{
得到{
回归锦标赛;
}
}
私人名单(锦标赛),;
}
要记住一些重要的事情:

  • 始终将其设置为只读属性。这有时会让人感到困惑,特别是如果您有一些可修改的内容,比如返回的是ICollection而不是IEnumerable。将属性设置为只读不会阻止对集合的修改,而是会阻止对整个列表的修改

  • 加载策略-在上面的示例中,您会注意到集合没有初始化。通常在构造函数中或首次访问属性时(称为惰性实例化)执行此操作-一般来说,惰性实例化会增加一些复杂性,但可以提高性能,特别是在不经常使用此集合或您有大量此类属性的情况下

  • 一般来说,在多对多的情况下,最好选择一个类来“容纳”另一个类(即,参与者有锦标赛属性,但锦标赛没有参与者属性,反之亦然)。这减少了您必须编写的代码量,并降低了复杂性和数据库的表面积。如果需要另一个方向调用,请考虑方法调用而不是属性。记住,关系意义上的多对多并不一定意味着这是常见的用例(作为用户,我可能只想将参与者添加到锦标赛中,而不是将锦标赛添加到参与者中)

  • 如果您的集合是可修改的,请记住,发送保存意味着它下面的集合如果被更改,也应该被修改。这会增加很多复杂性(在过去,我使用内部列表来存储添加/删除的项目)


如果您正在寻找面向对象(或领域驱动设计)的方法,那么第三个对象来处理“连接”是完全错误的。您可以将ILists/Enumerables与Add。。。处理此问题的方法如下:

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);
    }
}
公共课堂参与者
{
私有只读IList_=新列表();
公共数字锦标赛
{
获取{return}
}
内部冠军赛(冠军赛)
{
如果(!\u锦标赛。包含(锦标赛))
_锦标赛。添加(锦标赛);
}
}
公开课冠军赛
{
私有只读IList_参与者=新列表();
公众参与人数
{
获取{return\u参与者;}
}
公共无效添加参与者(参与者)
{
如果(_participants.Contains(participant))返回;
_参与者。添加(参与者);
参与者。AddChampion(本次);
}
}

这里的关键是确保您只从一方管理关系-例如,在这种情况下,可以通过调用champosion.AddParticipant()

很好的答案!最后一句话至关重要。。。你应该大胆点+1.