Frage

Ich habe zwei Entitäten Foo und Bar mit einer Viele-zu-viele-Beziehung zwischen ihnen.

Nehmen wir an, es gibt keine semantische Argument dafür, warum Foo sein könnte „verantwortlich“ für die viele zu viele Beziehungen, aber wir entscheiden willkürlich, dass Foo für die Beziehung verantwortlich ist (dh in NHibernate würden wir Bar als Inverse markieren)

Das ist alles schön und gut aus einer DB Perspektive, aber meine Einheit APIs offenbart ein Problem.

    // Responsible for the relation
    public class Foo
    {
        List<Bar> Bars = new List<Bar>();

        public void AddBar(Bar bar)
        {
            Bars.Add(bar);
            bar.AddFoo(this);
        }
    }

    public class Bar
    {
        List<Foo> Foos = new List<Foo>();

        // This shouldn't exist.
        public void AddFoo(Foo foo)
        {
            Foos.Add(foo);
            foo.AddBar(this); // Inf Recursion
        }
    }

Wenn wir entschieden haben, dass Foo für diese Beziehung verantwortlich sind, wie aktualisiere ich die zugehörige Sammlung in Bar ohne eine öffentliche Bar.AddFoo () Methode zu schaffen, die nicht einmal existieren?

Ich fühle mich wie ich in der Lage sein sollte, die diese Stellen vom DB nach einer Operation, wie dies die Integrität meines Domain-Modells zu halten, ohne auf neu zu laden.

UPDATE: Code zwicken von commenter inspiriert.

War es hilfreich?

Lösung

Sie haben gesagt, dass eine Seite wird „besitzen“ die Beziehung. Machen Sie diese Methode public. Die anderen Verbände (oder Methoden hinzufügen) intern gemacht werden können die Verbraucher zu vermeiden, direkt mit ihr zu interagieren.

public class Foo
{  
   private IList<Bar> Bars {get;set;}

   public void AddBar(Bar bar)
   {
      Bars.Add(bar);
      bar.Foos.Add(this);
   }
}

public class Bar
{
   internal IList<Foo> Foos {get;set;}
}

Andere Tipps

Sie können ein Domain-Konzept dort fehlen. Haben Sie versucht, eine dritte Einheit zu schaffen: FooBarRelationship

Siehe arbeiten bidirektionale Verbindungen in der Hibernate-Dokumentation.

  

Viele Entwickler Programm defensiv   und erstellen Methoden Link-Management   korrekt beiden Seiten gesetzt, z.B. im   Person:

protected Set getEvents() {
    return events;
}

protected void setEvents(Set events) {
    this.events = events;
}

public void addToEvent(Event event) {
    this.getEvents().add(event);
    event.getParticipants().add(this);
}

public void removeFromEvent(Event event) {
    this.getEvents().remove(event);
    event.getParticipants().remove(this);
}

Ich persönlich denke, Entity-Objekt die Liste der zugehörigen Objekthalte zu klug ist, zu sein, und man sollte die DAL lassen die Datenbank getroffen.

DALFactory.FooAdapter.getBars(foo);

Sie könnte es statisch machen

public class Foo
{
    List<Bar> Bars = new List<Bar>();

    public void AddBar(Bar bar)
    {
        Bars.Add(bar);
        Bar.AddFoo(bar,this);
    }
}

public class Bar
{
    List<Foo> Foos = new List<Foo>();

    // This shouldn't exist.
    public static void AddFoo(Bar bar, Foo foo)
    {
        bar.Foos.Add(foo);
        //foo.AddBar(this); inf recurtion
    }
}

Nicht wirklich ideal, aber es kommt die Funktion aus dem Objekt seiner selbst

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top