NHibernate - Cascades

Bu bölümde, Cascade özelliğinin nasıl kullanılacağını ele alacağız. Bir dizi veya bir öğe koleksiyonunuz veya müşterimiz ve siparişimiz gibi iki sınıf arasında bir ilişkiniz varsa ve yabancı anahtar ilişkiniz varsa. Müşteriyi varsayılan olarak silersek, NHibernate alt nesnelere hiçbir şey yapmaz, bu nedenle o müşteriye ait olanlar ve biz yetim siparişler olabilir.

  • Basamaklı kavramını kullanabilmemiz için yabancı anahtar kısıtlamalarını da ihlal ediyor olabiliriz.

  • Varsayılan olarak, NHibernate işlemleri alt nesnelere basamaklamaz.

  • Bunun nedeni, varsayılan bir gönderim adresine sahip bir müşteri gibi ilişkilerinizin olabilmesi ve bu gönderim adresinin birçok farklı müşteri ile paylaşılmasıdır.

  • Dolayısıyla, bu ilişkiyi ille de basamaklandırmak istemezsiniz, çünkü diğer müşteriler hala onunla ilgilidir.

  • Dolayısıyla, kademeli kavramın tamamı NHibernate'e alt varlıklarını nasıl idare edeceğini söylemektir.

Basamaklama için aşağıdaki gibi farklı seçenekler vardır -

  • none - bu varsayılandır ve basamaksız olduğu anlamına gelir.

  • all - kayıtlar, güncellemeler ve silmeleri basamaklandıracak.

  • save-update - kademeli, kaydeder ve günceller.

  • delete - silme işlemlerini basamaklandıracaktır.

  • all-delete-orphan - Oldukça sık kullanılan ve Hepsi Hariç Tümü ile aynı olan özel bir dosyadır, Sil-öksüz satırları bulursa bunları da siler.

Varsayılanı şurada belirtebilirsiniz: hbm.xml dosya, böylece o Hazırda Bekletme eşleme öğesinde varsayılan bir basamaklama sağlayabilir veya bunu çoktan bire gibi belirli koleksiyonlar ve ilişkiler için de belirtebilirsiniz.

Basit örnek kademelere bir göz atalım, aşağıdaki kodda gösterildiği gibi kaydetmeyi siparişlere manuel olarak kademelendirmemiz gereken programdaki sorunu çözelim.

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

Yukarıdaki kod parçacığında, müşteri için tüm siparişleri manuel olarak kaydettiğimizi görebilirsiniz. Şimdi tüm siparişlerin kaydedildiği manuel basamaklı kodu kaldıralım.

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

Basamaklı seçeneğini belirtmemiz gerekiyor 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>
  • Artık siparişler tamamen müşteriye aittir. Dolayısıyla, müşteriler veri tabanından silinmişse, buradaki uygulamamız, sahipsiz kalmış olanlar da dahil olmak üzere tüm bu siparişleri silmek isteyecektir.

  • Bir silme işlemi sona erecek. Bununla, müşteri kimliğinin sildiğiniz müşteriye eşit olduğu sipariş tablosundan sil diyecektir.

  • Böylece bu silme işlemlerini gerçekten basamaklandırabilirsiniz. YaniAll, kaydeder, günceller ve siler.

Şimdi bu uygulamayı çalıştırdığınızda, aşağıdaki çıktıyı göreceksiniz.

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

Gördüğünüz gibi manuel olarak basamaklanan kodu programdan sildik ve uygulamamız hala çalışıyor.

Yani ilişkinize bağlı olarak, bunları basamaklamak isteyebilirsiniz. Şimdi, farklı bir kademeli ilişkiye bakalım. Hadi gidelimOrder.hbm.xml dosya ve bu çoka bir ilişkiyi basamaklandırabiliriz.

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

Yani yeni bir sipariş oluşturursak ve ona eklenen yeni bir müşteri varsa ve biz de bu siparişi kaydedin, bunu kademelendirmek isteyebiliriz. Ancak muhtemelen yapmak istemeyeceğimiz bir şey, ilgili müşteriyi silmek için bir siparişin silinmesidir.

Bu yüzden burada, bir kaydetme güncellemesi yapmak isterdik, bu nedenle bir kaydetme güncellemesi kullanarak, bu müşteriye herhangi bir kaydetme veya güncellemeyi basamaklandıracaktır. Yani, yeni bir müşteri alırsak veya müşteriyi değiştiriyorsak, bunu basamaklandıracaktır. Silme ise, bunu veritabanından silmez.

Yani uygulamamızı tekrar çalıştırmak, her şey hala beklendiği gibi çalışıyor.

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

Şimdi uygulamanıza bir göz atmalısınız, varsayılanın Yok olduğunu ve varlıklarınızın her biri için uygun basamakları ve bu veritabanındaki her bir ilişkiyi belirlemek için varlıklar ve bunlar arasındaki ilişkiler hakkında düşünmeniz gerektiğini unutmayın.