8 Stimmen

Viele-zu-viele-Objekt-zu-Objekt-Beziehung in C#

Ich arbeite an einem kleinen Bildungsprojekt zur Übung von perst.net.

Wir haben ein kleines Design-Problem, nämlich wie man die Beziehung zwischen zwei Objektklassen am besten auflöst, d.h. die Teilnehmer y Meisterschaft . Es ist eine Beziehung von vielen zu vielen, denn Teilnehmer können an vielen Veranstaltungen teilnehmen Meisterschaften y Meisterschaften kann ein Mehrfaches haben Teilnehmer .

Bitte beraten Sie, wie man dies am besten in C# zu tun, sollte ich die "relationale DB wie" technische Klasse verwenden?

10voto

Steve Willcock Punkte 24787

Wenn Sie einen objektorientierten (oder bereichsorientierten) Ansatz suchen, dann ist ein drittes Objekt, das die "Verbindung" handhabt, der völlig falsche Weg, dies zu tun. Sie können ILists / Enumerables mit Add... Methoden verwenden, um dies wie folgt zu behandeln:

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

Wichtig ist hier, dass die Beziehung nur von einer Seite aus verwaltet wird, z. B. in diesem Fall durch den Aufruf von championship.AddParticipant()

4voto

Ryan Brunner Punkte 14463

Sie können eine beliebige Beziehung haben, bei der ein bestimmtes Element mehrere mit ihm verbundene Elemente haben kann, indem Sie IEnumerable (oder eine andere Sammlung) verwenden. In Ihrem Beispiel würde dies wie folgt aussehen:

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

Einige wichtige Dinge sind zu beachten:

  • Machen Sie diese Eigenschaft immer zu einer schreibgeschützten Eigenschaft. Dies ist manchmal verwirrend, vor allem, wenn Sie etwas Veränderbares wie eine ICollection statt einer IEnumerable zurückgegeben haben. Wenn Sie die Eigenschaft schreibgeschützt machen, verhindert dies nicht die Änderung der Sammlung aber die Änderung der gesamte Liste .

  • Ladestrategien - Sie werden feststellen, dass im obigen Beispiel die Sammlung nicht initalisiert ist. In der Regel geschieht dies entweder im Konstruktor oder beim ersten Zugriff auf die Eigenschaft (so genannte "Lazy Instantiation"). Im Allgemeinen erhöht die "Lazy Instantiation" die Komplexität, kann aber auch die Leistung steigern, insbesondere wenn die Sammlung nicht oft verwendet wird oder Sie viele Eigenschaften dieser Art haben.

  • Im Allgemeinen ist es eine gute Idee, eine Klasse zu wählen, die die andere Klasse im Falle von many-to-many "hält" (d.h. Teilnehmer haben Eigenschaften von Meisterschaften, aber Meisterschaften haben keine Eigenschaften von Teilnehmern oder umgekehrt). Dies verringert die Menge an Code, die Sie schreiben müssen, und reduziert die Komplexität und die Oberfläche Ihrer Datenbank. Wenn ein Aufruf für die andere Richtung erforderlich ist, sollten Sie eher einen Methodenaufruf als eine Eigenschaft in Betracht ziehen. Denken Sie daran, dass "many-to-many" im relationalen Sinne nicht unbedingt bedeutet, dass dies der übliche Anwendungsfall ist (als Benutzer möchte ich vielleicht nur Teilnehmer zu Meisterschaften hinzufügen und nicht Meisterschaften zu Teilnehmern).

  • Wenn Ihre Sammlung änderbar ist, denken Sie daran, dass das Senden einer Speicherung bedeutet, dass die darunter liegenden Sammlungen ebenfalls geändert werden sollten, wenn sie geändert wurden. Dies kann eine Menge Komplexität hinzufügen (in der Vergangenheit habe ich interne Listen verwendet, um hinzugefügte/gelöschte Elemente zu speichern)

1voto

Ich bin nicht sicher, ob dies für Ihr Design oder Ihre Anforderungen geeignet ist, aber es könnte möglich sein...

Offensichtlich lässt sich eine Many-to-many-Beziehung am einfachsten mit einem dritten Objekt darstellen, das die Beziehung verwaltet. In Ihrem Fall wäre das ein championshipp-Teilnehmer . Anstatt eine Sammlung in Ihrer Teilnehmerklasse zu haben, die Meisterschaften enthält und umgekehrt, lassen Sie sie eine Instanz dieser dritten Klasse enthalten. Die championshipp-Teilnehmer Objekt verwaltet diese Beziehung. Es kann dann direkt als Kreuzungstabelle in die Datenbank serialisiert werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X