แอตทริบิวต์ผกผันใน NHibernate


89

ฉันจะใช้ Inverse Attribute ได้อย่างไร? ถ้าฉันจำไม่ผิดสำหรับความสัมพันธ์หนึ่งถึงหลายความสัมพันธ์ต้องตั้งค่าแอตทริบิวต์ผกผันเป็นจริง สำหรับความสัมพันธ์แบบกลุ่มต่อกลุ่มต้องตั้งค่าแอตทริบิวต์ผกผันของคลาสเอนทิตีหนึ่งรายการเป็นจริงและอีกชุดหนึ่งเป็นเท็จ

ใคร ๆ ก็ส่องไฟเรื่องนี้ได้บ้าง


2
คุณยังสามารถตรวจสอบคำตอบของฉัน " เมื่อใดควรใช้ผกผัน =" จริง | เท็จ " " ในคำถามที่คล้ายกัน
Daniel Schilling

คำตอบ:


126

ต้องไม่ตั้งค่าแอตทริบิวต์ผกผันเป็นจริง ...

คุณใช้แอตทริบิวต์ผกผันเพื่อระบุ "เจ้าของ" ของการเชื่อมโยง (การเชื่อมโยงสามารถมีเจ้าของได้เพียงคนเดียวดังนั้นปลายด้านหนึ่งจะต้องถูกตั้งค่าเป็นผกผันอีกด้านหนึ่งจะต้องตั้งค่าเป็น 'ไม่ผกผัน') (เจ้าของ: inverse=false; ไม่ใช่เจ้าของ: inverse=true)

ในการเชื่อมโยงแบบหนึ่งต่อกลุ่มหากคุณไม่ได้ทำเครื่องหมายคอลเลกชันเป็นส่วนปลายผกผัน NHibernate จะทำการอัปเดตเพิ่มเติม ในความเป็นจริงในกรณีนี้ NHibernate จะแทรกเอนทิตีที่มีอยู่ในคอลเลกชันก่อนหากจำเป็นให้แทรกเอนทิตีที่เป็นเจ้าของคอลเลกชันและหลังจากนั้นจะอัปเดต 'เอนทิตีการรวบรวม' เพื่อให้มีการตั้งค่าคีย์ต่างประเทศและการเชื่อมโยง ทำ. (โปรดทราบว่านี่หมายความว่าคีย์ภายนอกในฐานข้อมูลของคุณควรเป็นโมฆะ)

เมื่อคุณทำเครื่องหมายจุดสิ้นสุดคอลเลกชันเป็น 'ผกผัน' จากนั้น NHibernate จะยังคงอยู่ในเอนทิตีที่ 'เป็นเจ้าของ' คอลเลกชันก่อนและจะคงอยู่ในเอนทิตีที่อยู่ในคอลเลกชันหลังจากนั้นโดยหลีกเลี่ยงคำสั่ง UPDATE เพิ่มเติม

ดังนั้นในการเชื่อมโยงสองทิศทางคุณจะมีปลายผกผันหนึ่งเสมอ


4
สิ่งนี้อธิบายทุกอย่างเพื่อเพิ่มเจ้าของคือสิ่งที่มีคีย์ต่างประเทศในตาราง
Brijesh Mishra

48
ในความคิดของฉันนี่เป็นคำศัพท์ที่ไม่ดีจริงๆ ทำไมไม่ทำเครื่องหมายแสดงความเป็นเจ้าของแทนที่จะเป็น 'ผกผัน'!
UpTheCreek

1
+1 สำหรับการใช้การปฏิเสธในคำที่ถูกลบไปแล้ว :) "แอตทริบิวต์ INVERSE ต้องไม่ถูกตั้งค่าเป็น true"
contactmatt

คำตอบที่ดีคำถามเดียวที่เหลืออยู่คือการตัดสินใจว่าใครควรเป็น "เจ้าของ"
PandaWood

แล้วหลายต่อหลายคนเมื่อคุณมีตารางกลางที่เก็บความสัมพันธ์ระหว่าง 2 เอนทิตี?
Dark_Knight

10

นอกเหนือจากคำตอบข้างต้นและตามความเข้าใจของฉันคุณต้องคงค่าคีย์ต่างประเทศในคอลเล็กชันด้วยตนเองนั่นคือถ้าคุณไม่ต้องการคำสั่งอัพเดตเพิ่มเติม

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

สำหรับคำอธิบายเพิ่มเติมเกี่ยวกับแอตทริบิวต์ผกผันตรวจสอบโพสต์ต่อไปนี้:

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


2

ฉันเห็นว่า "เจ้าของ" เข้ามาที่ใด แต่การเชื่อมโยงเป็นท่อและคุณสามารถมองลงไปที่ปลายด้านใดด้านหนึ่งดังนั้นจะบอกว่าเอนทิตีใด "เป็นเจ้าของ" ไปป์

วิธีที่แตกต่างกันในการมองสิ่งนี้คือในความสัมพันธ์แบบหนึ่งต่อกลุ่มที่จริงมี 2 ความสัมพันธ์เกิดขึ้น

ความสัมพันธ์ 1: ผู้ปกครองกับเด็กหลายคน

ความสัมพันธ์ 2: เด็กแต่ละคนกับผู้ปกครอง

ดังนั้น NH จะพยายามรัน sql เพื่อเก็บสิ่งเหล่านี้ไว้ในฐานข้อมูล แต่ไม่จำเป็นต้องเป็นเพราะเมื่อคุณตั้ง Foreign Key เช่นในความสัมพันธ์ 2 เมื่อเด็กถูกเก็บไว้ระบบจะแก้ไขความสัมพันธ์ของผู้ปกครองกับเด็กโดยอัตโนมัติเช่นกันเนื่องจากความสัมพันธ์ 1 เป็น "ผกผัน" ของความสัมพันธ์ 2 .

หมายความว่าผกผันมันเป็นสิ่งที่เราได้รับโดยค่าเริ่มต้นเมื่อเราตั้งค่าความสัมพันธ์หลัก กล่าวคือไม่จำเป็นต้องให้ NH รัน sql เพื่อแก้ไขความสัมพันธ์ 1 และการทำเครื่องหมายคอลเลกชันเด็กเป็น Inverse NH จะข้ามการรัน sql เมื่อมีการเพิ่มคอลเล็กชันลูก

ฉันคิดว่าถ้าคุณไม่บอก NH ว่ามันเป็นอินเวอร์สก็จะเสียความพยายามในการทำ sql เพื่อพยายามกำหนดความสัมพันธ์แบบผกผันเช่นกันแม้ว่ามันจะไม่จำเป็นก็ตาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.