NHibernate - พรู
ในบทนี้เราจะพูดถึงวิธีการใช้คุณลักษณะ Cascade หากคุณมีชุดหรือคอลเลกชันของรายการหรือความสัมพันธ์ระหว่างสองชั้นเรียนเช่นลูกค้าและคำสั่งซื้อของเราและมีความสัมพันธ์คีย์ต่างประเทศ หากเราลบลูกค้าโดยค่าเริ่มต้น NHibernate จะไม่ทำอะไรกับออบเจ็กต์ลูกดังนั้นสิ่งที่เป็นของลูกค้านั้นและเราอาจเป็นคำสั่งซื้อที่ไม่ได้รับการดูแล
นอกจากนี้เรายังอาจละเมิดข้อ จำกัด ของคีย์ต่างประเทศดังนั้นเราจึงสามารถใช้แนวคิดเรื่องการเรียงซ้อนได้
ตามค่าเริ่มต้น NHibernate จะไม่เรียงซ้อนการดำเนินการไปยังวัตถุลูก
เหตุผลนี้ก็คือคุณสามารถมีความสัมพันธ์เช่นลูกค้ามีที่อยู่จัดส่งเริ่มต้นและที่อยู่จัดส่งจะแชร์กับลูกค้าหลาย ๆ คน
ดังนั้นคุณจึงไม่ต้องการลดทอนความสัมพันธ์นั้นเพราะลูกค้ารายอื่นยังคงอ้างถึง
ดังนั้นแนวคิดทั้งหมดของการลดหลั่นคือการบอก NHibernate ถึงวิธีจัดการกับเอนทิตีลูกของมัน
มีตัวเลือกที่แตกต่างกันสำหรับการเรียงซ้อนซึ่งมีดังนี้ -
none - ซึ่งเป็นค่าเริ่มต้นและหมายความว่าไม่มีการเรียงซ้อน
all - ซึ่งจะบันทึกอัปเดตและลบ
save-update - มันจะเรียงซ้อนบันทึกและอัปเดต
delete - มันจะลบน้ำตก
all-delete-orphan - เป็นรายการพิเศษที่ใช้บ่อยและเหมือนกับ All except หากพบแถว Delete-orphan ก็จะลบออกเช่นกัน
คุณสามารถระบุค่าเริ่มต้นในไฟล์ hbm.xml เพื่อให้คุณสามารถจัดเตรียมน้ำตกเริ่มต้นบนองค์ประกอบการแมปไฮเบอร์เนตนั้นหรือคุณสามารถระบุสำหรับคอลเล็กชันและความสัมพันธ์ที่เฉพาะเจาะจงเช่นหลายต่อหนึ่ง
มาดูตัวอย่างการเรียงซ้อนกันอย่างง่ายๆกันเถอะแก้ไขปัญหาในโปรแกรมโดยที่เราต้องเรียงลำดับการบันทึกไปยังคำสั่งด้วยตนเองดังที่แสดงในโค้ดต่อไปนี้
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var newCustomer = CreateCustomer();
Console.WriteLine("New Customer:");
Console.WriteLine(newCustomer);
session.Save(newCustomer);
foreach (var order in newCustomer.Orders) {
session.Save(order);
}
id = newCustomer.Id;
tx.Commit();
}
ในข้อมูลโค้ดด้านบนคุณจะเห็นว่าเรากำลังบันทึกคำสั่งซื้อทั้งหมดสำหรับลูกค้าด้วยตนเอง ตอนนี้เรามาลบรหัสน้ำตกด้วยตนเองซึ่งคำสั่งซื้อทั้งหมดจะถูกบันทึกไว้
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var newCustomer = CreateCustomer();
Console.WriteLine("New Customer:");
Console.WriteLine(newCustomer);
session.Save(newCustomer);
id = newCustomer.Id;
tx.Commit();
}
เราจำเป็นต้องระบุตัวเลือกการเรียงซ้อนใน customer.hbm.xml.
<?xml version = "1.0" encoding = "utf-8" ?>
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemo"
namespace = "NHibernateDemo">
<class name = "Customer">
<id name = "Id">
<generator class = "guid.comb"/>
</id>
<property name = "FirstName"/>
<property name = "LastName"/>
<property name = "AverageRating"/>
<property name = "Points"/>
<property name = "HasGoldStatus"/>
<property name = "MemberSince" type = "UtcDateTime"/>
<property name = "CreditRating" type = "CustomerCreditRatingType"/>
<component name = "Address">
<property name = "Street"/>
<property name = "City"/>
<property name = "Province"/>
<property name = "Country"/>
</component>
<set name = "Orders" table = "`Order`" cascade = "all-delete-orphan">
<key column = "CustomerId"/>
<one-to-many class = "Order"/>
</set>
</class>
</hibernate-mapping>
ตอนนี้คำสั่งซื้อทั้งหมดเป็นของลูกค้า ดังนั้นหากลูกค้าถูกลบออกจากฐานข้อมูลแอปพลิเคชันของเราจะต้องการลบคำสั่งซื้อเหล่านั้นทั้งหมดรวมถึงคำสั่งซื้อที่อาจถูกละเลยด้วย
มันจะจบลงด้วยการลบ จากนั้นจะมีข้อความว่าลบออกจากตารางคำสั่งซื้อโดยที่รหัสลูกค้าเท่ากับลูกค้าที่คุณกำลังลบ
ดังนั้นคุณสามารถเรียงซ้อนการลบเหล่านี้ได้ ดังนั้นด้วยAllมันจะทำการบันทึกอัปเดตและลบ
ตอนนี้เมื่อคุณเรียกใช้แอปพลิเคชันนี้คุณจะเห็นผลลัพธ์ต่อไปนี้
New Customer:
John Doe (00000000-0000-0000-0000-000000000000)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
CreditRating: Good
AverageRating: 42.42424242
Orders:
Order Id: 00000000-0000-0000-0000-000000000000
Order Id: 00000000-0000-0000-0000-000000000000
Reloaded:
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
The orders were ordered by:
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
Press <ENTER> to exit...
ดังที่คุณเห็นว่าเราได้ลบโค้ดออกจากโปรแกรมที่เรียงซ้อนด้วยตนเองและแอปพลิเคชันของเรายังคงทำงานอยู่
ดังนั้นขึ้นอยู่กับความสัมพันธ์ของคุณคุณอาจต้องการเรียงซ้อนกัน ตอนนี้เรามาดูความสัมพันธ์แบบเรียงซ้อนกัน ไปที่ไฟล์Order.hbm.xml ไฟล์และเราสามารถเรียงซ้อนความสัมพันธ์แบบกลุ่มต่อหนึ่ง
<?xml version = "1.0" encoding = "utf-8" ?>
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemo"
namespace = "NHibernateDemo">
<class name = "Order" table = "`Order`">
<id name = "Id">
<generator class = "guid.comb"/>
</id>
<property name = "Ordered"/>
<property name = "Shipped"/>
<component name = "ShipTo">
<property name = "Street"/>
<property name = "City"/>
<property name = "Province"/>
<property name = "Country"/>
</component>
<many-to-one name = "Customer" column = "CustomerId" cascade = "save-update"/>
</class>
</hibernate-mapping>
ดังนั้นหากเราสร้างคำสั่งซื้อใหม่และมีลูกค้าใหม่ติดอยู่และเราบอกว่าบันทึกคำสั่งซื้อนั้นเราอาจต้องการเรียงลำดับ แต่สิ่งหนึ่งที่เราอาจไม่ต้องการทำคือหากคำสั่งซื้อถูกลบเพื่อลบลูกค้าที่เกี่ยวข้อง
ดังนั้นที่นี่เราต้องการทำการอัปเดตแบบบันทึกดังนั้นการใช้การบันทึกการอัปเดตจะเป็นการเรียงลำดับการบันทึกหรืออัปเดตให้กับลูกค้ารายนั้น ดังนั้นหากเราได้ลูกค้าใหม่หรือกำลังเปลี่ยนลูกค้าก็จะลดหลั่นกันไป หากเป็นการลบจะไม่ลบสิ่งนั้นออกจากฐานข้อมูล
ดังนั้นเรียกใช้แอปพลิเคชันของเราอีกครั้งทุกอย่างยังคงทำงานตามที่คาดไว้
New Customer:
John Doe (00000000-0000-0000-0000-000000000000)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
CreditRating: Good
AverageRating: 42.42424242
Orders:
Id: 00000000-0000-0000-0000-000000000000
Order Id: 00000000-0000-0000-0000-000000000000
Reloaded:
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
The orders were ordered by:
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
John Doe (10b2a3d7-7fcf-483c-b1da-a5bb00b8512e)
Points: 100
HasGoldStatus: True
MemberSince: 1/1/2012 12:00:00 AM (Utc)
CreditRating: Good
AverageRating: 42.4242
Orders:
Order Id: e6680e30-5b3b-4efa-b017-a5bb00b85133
Order Id: b03858e7-8c36-4555-8878-a5bb00b85134
Press <ENTER> to exit...
ตอนนี้คุณควรดูแอปพลิเคชันของคุณโปรดจำไว้ว่าค่าเริ่มต้นคือไม่มีและคุณต้องคิดถึงเอนทิตีของคุณและความสัมพันธ์ระหว่างพวกเขาเพื่อกำหนดการเรียงซ้อนที่เหมาะสมสำหรับแต่ละเอนทิตีของคุณรวมถึงความสัมพันธ์ของคุณในฐานข้อมูลนั้นด้วย