NHibernate-カスケード

この章では、カスケード機能の使用方法について説明します。アイテムのセットまたはコレクション、または顧客と注文などの2つのクラス間の関係があり、外部キー関係がある場合。デフォルトで顧客を削除した場合、NHibernateは子オブジェクトに対して何も行わないため、その顧客に属するものは、注文を孤立させる可能性があります。

  • また、外部キー制約に違反している可能性があるため、カスケードの概念を使用できます。

  • デフォルトでは、NHibernateは操作を子オブジェクトにカスケードしません。

  • これは、デフォルトの配送先住所を持つ顧客などの関係を築くことができ、配送先住所が多くの異なる顧客と共有されるためです。

  • したがって、他の顧客がまだそれを参照しているため、必ずしもその関係をカスケードする必要はありません。

  • したがって、カスケードの全体的な概念は、NHibernateにその子エンティティを処理する方法を指示することです。

カスケードにはさまざまなオプションがあり、次のとおりです。

  • none −これはデフォルトであり、カスケードがないことを意味します。

  • all −これは、保存、更新、および削除をカスケードします。

  • save-update −カスケード、保存、更新します。

  • delete −削除をカスケードします。

  • all-delete-orphan −これは非常に頻繁に使用される特別なものであり、すべてを除いて同じです。削除孤立行が見つかった場合は、それらも削除されます。

でデフォルトを指定できます hbm.xml ファイルなので、そのHibernateマッピング要素にデフォルトのカスケードを提供することも、多対1などの特定のコレクションや関係に指定することもできます。

カスケードの簡単な例を見てみましょう。プログラムの問題を修正しましょう。次のコードに示すように、保存を注文に手動でカスケードする必要があります。

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>
  • 現在、注文は完全に顧客のものです。したがって、顧客がデータベースから削除された場合、ここでのアプリケーションは、孤立している可能性のある注文を含め、それらの注文をすべて削除する必要があります。

  • 削除を行うことになります。これにより、注文テーブルから削除と表示されます。ここで、顧客IDは、削除する顧客と同じです。

  • したがって、実際にこれらの削除をカスケードできます。だからと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 ファイルを作成すると、その多対1の関係をカスケードできます。

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

したがって、新しい注文を作成し、それに添付された新しい顧客がいて、その注文を保存すると言う場合、それをカスケードすることができます。しかし、おそらくやりたくないことの1つは、注文が削除されて対応する顧客が削除された場合です。

したがって、ここでは、保存更新を実行する必要があるため、保存更新を使用すると、保存または更新がその顧客にカスケードされます。したがって、新しい顧客を獲得した場合、または顧客を変更する場合は、それをカスケードします。削除の場合、データベースから削除されません。

したがって、アプリケーションを再度実行しても、すべてが期待どおりに機能します。

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

ここで、アプリケーションを確認する必要があります。デフォルトはNoneであり、エンティティとそれらの間の関係を考慮して、各エンティティとそのデータベース内の各関係に適切なカスケードを決定する必要があることを忘れないでください。