Attributo inverso in NHibernate


89

Come si usa l'attributo inverso? Se non sbaglio, per una relazione uno a molti l'attributo inverso deve essere impostato su true. Per le relazioni molti-a-molti, uno degli attributi inversi della classe di entità deve essere impostato su true e un altro su false.

Qualcuno può far luce su questo?


2
Puoi anche controllare la mia risposta, " Quando usare inverse =" true | false " ", su una domanda simile.
Daniel Schilling

Risposte:


125

L'attributo inverso non deve essere impostato su true ...

Usa l'attributo inverso per specificare il "proprietario" dell'associazione. (Un'associazione può avere un solo proprietario, quindi un'estremità deve essere impostata su inversa, l'altra deve essere impostata su "non inversa"). (Proprietario inverse=false:; Non proprietario inverse=true:)

In un'associazione uno-a-molti, se non contrassegni la raccolta come estremità inversa, NHibernate eseguirà un AGGIORNAMENTO aggiuntivo. In questo caso, infatti, NHibernate inserirà prima l'entità contenuta nella collezione, se necessario inserirà l'entità proprietaria della collezione, e successivamente aggiornerà la 'collection entity', in modo che venga impostata la chiave esterna e l'associazione è realizzato. (Nota che questo significa anche che la chiave esterna nel tuo DB dovrebbe essere nullable).

Quando si contrassegna la fine della raccolta come "inversa", NHibernate prima persisterà l'entità che "possiede" la raccolta e in seguito manterrà le entità che si trovano nella raccolta, evitando un'istruzione UPDATE aggiuntiva.

Quindi, in un'associazione bidirezionale, hai sempre un'estremità inversa.


4
Questo spiega tutto solo per aggiungere il proprietario è uno che ha una chiave esterna nella tabella
Brijesh Mishra

48
Secondo me questa è davvero una pessima terminologia. Perché non contrassegnare la proprietà piuttosto che il "inverso" ?!
UpTheCreek

1
+1 per l'utilizzo della negazione su un termine già negato :) "L'attributo INVERSO NON DEVE essere impostato su true"
contactmatt

Buona risposta, l'unica domanda rimasta è come decidere chi dovrebbe essere il "proprietario"
PandaWood

Che dire di molti-a-molti quando hai una tabella centrale che contiene la relazione tra 2 entità?
Dark_Knight

10

Oltre alla risposta sopra , e secondo la mia comprensione, è necessario persistere manualmente il valore della chiave esterna nella raccolta, ovvero se non si desidera l'istruzione di aggiornamento aggiuntiva:

Parent par = Session.Get<Parent>(8);

Child ch = new Child();
ch.Name = "Emad";

//set the parent foreign key manually
ch.MyParent = par;

par.MyChildren.Add(ch);
Session.Save(par);

per ulteriori spiegazioni sull'attributo inverso, controlla il seguente post:

http://www.emadashi.com/index.php/2008/08/nhibernate-inverse-attribute/


2

Posso vedere dove entra in gioco il "proprietario", ma un'associazione è una pipe e puoi guardare in entrambe le estremità, quindi cosa dire quale entità "possiede" la pipe.

Un modo diverso di vedere questo è che in una relazione Uno a Molti, ci sono in realtà 2 relazioni in corso.

Relazione 1: genitore di molti bambini.

Relazione 2: ogni bambino con un genitore

Quindi NH tenterà di eseguire sql per memorizzare ciascuno di questi nel DB. Ma non è necessario perché quando si imposta la chiave esterna, ad esempio nella relazione 2, quando viene memorizzato un figlio, viene automaticamente stabilita anche la relazione di un genitore con il bambino perché la relazione 1 è "inversa" della relazione 2 .

Quindi significa inverso, è qualcosa che otteniamo per impostazione predefinita una volta impostata la relazione principale. cioè non è necessario che NH esegua sql per correggere la relazione 1 e contrassegnando la raccolta bambini come NH inverso salterà l'esecuzione di sql quando la raccolta bambini viene aggiunta a.

Presumo che se non dicessi a NH che era un inverso, allora sarebbe sprecato lo sforzo di fare sql per cercare di impostare anche la relazione inversa, anche se non era necessario.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.