web-dev-qa-db-fra.com

Attribut inverse dans NHibernate

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 sur false.

N'importe qui peut faire la lumière là-dessus?

87
Graviton

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érez l'entité qui possède la collection, et ensuite, met à 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 pouvoir être annulée).

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

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

121

En plus de la réponse ci-dessus , et selon ma compréhension, vous devez conserver la valeur de la clé étrangère dans la collection manuellement, 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 l'article suivant:

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

10
Emad Alashi

Je peux voir où le "propriétaire" entre en jeu, mais une association est un tuyau, et vous pouvez regarder vers le bas à chaque extrémité, alors que dire de l'entité "propriétaire" du tuyau.

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 avec de nombreux 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 cela n'est pas nécessaire, car lorsque vous définissez la clé étrangère, par exemple dans la relation 2 lorsqu'un enfant est stocké, il a automatiquement corrigé la relation d'un parent à l'enfant également parce que la relation 1 est l '"inverse" de la relation 2.

Donc, inverse signifie, 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 réparer la relation 1 et en marquant la collection d'enfants comme un NH inverse, il sautera l'exécution de sql lorsque la collection d'enfants sera ajoutée.

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

2
Mickey Puri