Odwrotny atrybut w NHibernate

89

Jak używać Inverse Attribute? Jeśli się nie mylę, dla relacji jeden do wielu atrybut odwrotny musi być ustawiony na wartość true. W przypadku relacji wiele-do-wielu jeden z odwrotnych atrybutów klasy encji musi mieć wartość true, a drugi - wartość false.

Czy ktoś może rzucić na to trochę światła?

Graviton
źródło
2
Możesz również sprawdzić moją odpowiedź „ Kiedy używać inverse =" true | false " " na podobnym pytaniu.
Daniel Schilling,

Odpowiedzi:

126

Atrybut inverse nie może być ustawiony na true ...

Atrybut inverse służy do określenia „właściciela” powiązania. (Stowarzyszenie może mieć tylko jednego właściciela, więc jeden koniec musi być ustawiony na odwrotny, a drugi na „nieodwrotny”). (Właściciel: inverse=false; Non-właściciel: inverse=true)

W asocjacji jeden do wielu, jeśli nie oznaczysz kolekcji jako odwrotnego końca, NHibernate wykona dodatkową AKTUALIZACJĘ. W rzeczywistości w tym przypadku NHibernate najpierw wstawi jednostkę zawartą w kolekcji, w razie potrzeby wstawi jednostkę będącą właścicielem kolekcji, a następnie zaktualizuje `` jednostkę kolekcji '', aby ustawić klucz obcy i skojarzenie jest zrobione. (Zauważ, że oznacza to również, że klucz obcy w Twojej bazie danych powinien mieć wartość null).

Gdy oznaczysz koniec kolekcji jako „odwrotny”, NHibernate najpierw utrwali jednostkę, która jest „właścicielem” kolekcji, a następnie utrwali jednostki, które są w kolekcji, unikając dodatkowej instrukcji UPDATE.

Zatem w asocjacji dwukierunkowej zawsze masz jeden odwrotny koniec.

Frederik Gheysels
źródło
4
To wyjaśnia wszystko, aby dodać właściciela, który ma klucz obcy w tabeli
Brijesh Mishra
48
Moim zdaniem to naprawdę zła terminologia. Dlaczego nie zaznaczyć własności, a nie „odwrotnie” ?!
UpTheCreek
1
+1 za użycie negacji w już zanegowanym terminie :) "Atrybut INVERSE NIE MOŻE być ustawiony na wartość true"
contactmatt
Dobra odpowiedź, pozostaje tylko pytanie, jak zdecydować, kto powinien być „właścicielem”
PandaWood
A co z wieloma do wielu, gdy masz środkowy stół, który zawiera relację między dwoma podmiotami?
Dark_Knight,
10

Oprócz powyższej odpowiedzi i zgodnie z moim zrozumieniem, musisz ręcznie utrwalić wartość klucza obcego w kolekcji, czyli jeśli nie chcesz dodatkowej instrukcji aktualizacji:

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

dalsze wyjaśnienie atrybutu odwrotnego znajdziesz w następującym poście:

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

Emad Alashi
źródło
2

Widzę, do kogo wkracza „właściciel”, ale skojarzenie to potok i można spojrzeć w dół z dowolnego końca, więc co powiedzieć, która jednostka „jest właścicielem” rury.

Odmienny sposób patrzenia na to jest taki, że w relacjach jeden do wielu w rzeczywistości zachodzą 2 relacje.

Związek 1: Rodzic wielu dzieci.

Związek 2: każde dziecko z rodzicem

Więc NH spróbuje uruchomić sql, aby przechowywać każdy z nich w DB. Ale nie musi, ponieważ kiedy ustawisz klucz obcy, np. W relacji 2, gdy dziecko jest przechowywane, to automatycznie ustala również relację rodzica z dzieckiem, ponieważ relacja 1 jest „odwrotnością” relacji 2 .

Czyli odwrotność oznacza, że ​​jest to coś, co otrzymujemy domyślnie po ustawieniu głównej relacji. tj. nie ma potrzeby, aby NH uruchamiał sql, aby naprawić Relację 1 i oznaczając kolekcję dzieci jako odwrotną, NH pominie uruchamianie sql po dodaniu kolekcji child.

Przypuszczam, że jeśli nie powiesz NH, że to odwrotność, zmarnujesz wysiłek na wykonanie sql, aby spróbować ustawić odwrotną zależność również - nawet jeśli nie było to konieczne.

Mickey Puri
źródło