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

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