Attribut inverse dans NHibernate

89

Comment utiliser l'attribut inverse? Si je ne me trompe pas, pour une à plusieurs relations, l'attribut inverse doit être défini sur true. Pour les relations plusieurs-à-plusieurs, l'un des attributs inverses de la classe d'entité doit être défini sur true et un autre défini sur false.

Quelqu'un peut-il éclairer ce sujet?

Graviton
la source
2
Vous pouvez également vérifier ma réponse, " Quand utiliser inverse =" true | false " ", sur une question similaire.
Daniel Schilling

Réponses:

125

L'attribut inverse ne doit pas être défini sur true ...

Vous utilisez l'attribut inverse pour spécifier le «propriétaire» de l'association. (Une association ne peut avoir qu'un seul propriétaire, donc une extrémité doit être définie sur inverse, l'autre doit être définie sur «non inverse»). (Propriétaire: inverse=false; non-propriétaire: inverse=true)

Dans une association un-à-plusieurs, si vous ne marquez pas la collection comme extrémité inverse, NHibernate effectuera une MISE À JOUR supplémentaire. En fait, dans ce cas, NHibernate insérera d'abord l'entité qui est contenue dans la collection, si nécessaire insérera l'entité propriétaire de la collection, puis mettra à jour `` l'entité de collection '', de sorte que la clé étrangère soit définie et l'association est fait. (Notez que cela signifie également que la clé étrangère de votre base de données doit être Nullable).

Lorsque vous marquez la fin de la collection comme «inverse», alors NHibernate persistera d'abord l'entité qui «possède» la collection, et conservera ensuite les entités qui sont dans la collection, évitant une instruction UPDATE supplémentaire.

Ainsi, dans une association bidirectionnelle, vous avez toujours une extrémité inverse.

Frederik Gheysels
la source
4
Cela explique tout juste pour ajouter le propriétaire est celui qui a une clé étrangère dans la table
Brijesh Mishra
48
À mon avis, c'est vraiment une mauvaise terminologie. Pourquoi ne pas marquer la propriété plutôt que «l'inverse»?!
UpTheCreek
1
+1 pour utiliser la négation sur un terme déjà nié :) "L'attribut INVERSE NE DOIT PAS être mis à vrai"
contactmatt
Bonne réponse, la seule question qui reste est de savoir comment décider qui devrait être le "propriétaire"
PandaWood
Qu'en est-il de plusieurs à plusieurs lorsque vous avez une table du milieu qui contient la relation entre 2 entités?
Dark_Knight
10

En plus de la réponse ci - dessus , et selon ma compréhension, vous devez conserver manuellement la valeur de la clé étrangère dans la collection, c'est-à-dire si vous ne voulez pas l'instruction de mise à jour supplémentaire:

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

pour plus d'explications sur l'attribut inverse, consultez le post suivant:

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

Emad Alashi
la source
2

Je peux voir où le "propriétaire" entre en jeu, mais une association est un tube, et vous pouvez regarder vers le bas de chaque côté, alors que dire de quelle entité "possède" le tube.

Une autre façon de voir les choses est que dans une relation un à plusieurs, il y a en fait 2 relations en cours.

Relation 1: Parent à plusieurs enfants.

Relation 2: chaque enfant à un parent

NH tentera donc d'exécuter sql pour stocker chacun de ces éléments dans la base de données. Mais ce n'est pas nécessaire parce que lorsque vous définissez la clé étrangère, par exemple dans la relation 2 lorsqu'un enfant est stocké, alors il a automatiquement fixé la relation d'un parent à l'enfant car la relation 1 est l '«inverse» de la relation 2 .

Donc, inverse signifie que c'est quelque chose que nous obtenons par défaut une fois que nous avons défini la relation principale. c'est-à-dire qu'il n'est pas nécessaire pour NH d'exécuter sql pour corriger la relation 1 et en marquant la collection enfants comme Inverse, NH ignorera l'exécution de sql lorsque la collection enfants sera ajoutée.

Je suppose que si vous ne dites pas à NH que c'est l'inverse, alors cela gaspillerait des efforts en faisant SQL pour essayer de mettre en place la relation inverse également - même si ce n'était pas nécessaire.

Mickey Puri
la source