Domanda

Ho due entità Foo e Bar con una relazione Many to Many tra di loro.

Supponiamo che non vi siano argomenti semantici sul perché Foo potrebbe essere "responsabile". per la relazione molti a molti, ma decidiamo arbitrariamente che Foo è responsabile della relazione (ad esempio, in NHibernate contrassegneremo Bar come inverso)

Va ??benissimo dal punto di vista del DB, ma le API della mia entità rivelano un problema.

    // 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
        }
    }

Se abbiamo deciso che Foo è responsabile di questa relazione, come posso aggiornare la raccolta associata in Bar senza creare un metodo Bar.AddFoo () pubblico che non dovrebbe nemmeno esistere?

Sento che dovrei essere in grado di mantenere l'integrità del mio modello di dominio senza ricorrere a dover ricaricare queste entità dal DB dopo un'operazione come questa.

AGGIORNAMENTO: modifica del codice ispirata al commentatore.

È stato utile?

Soluzione

Hai detto che una parte "possiede". il rapporto. Rendi pubblico questo metodo. Le altre associazioni (o aggiungere metodi) possono essere rese interne per evitare che i consumatori interagiscano direttamente con esso.

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

Altri suggerimenti

Lì potresti perdere un concetto di dominio. Hai provato a creare una terza entità: FooBarRelationship?

Vedi Collegamenti bidirezionali funzionanti nella documentazione di Hibernate.

  

Molti sviluppatori programmano in modo difensivo   e creare metodi di gestione dei collegamenti a   impostare correttamente entrambi i lati, ad es. nel   Persona:

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

Personalmente penso che l'oggetto Entity che contiene l'elenco di oggetti correlati sia troppo intelligente e dovresti lasciare che DAL colpisca il database.

DALFactory.FooAdapter.getBars(foo);

potresti renderlo statico

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

Non proprio l'ideale ma toglie la funzione dall'oggetto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top