
- NHibernate 教程
- NHibernate - 首頁
- NHibernate - 概述
- NHibernate - 架構
- NHibernate - ORM
- NHibernate - 環境搭建
- NHibernate - 入門指南
- NHibernate - 基本 ORM
- NHibernate - 基本 CRUD 操作
- NHibernate - Profiler
- 為對映檔案新增 IntelliSense
- NHibernate - 資料型別對映
- NHibernate - 配置
- NHibernate - 覆蓋配置
- NHibernate - 批次大小
- NHibernate - 快取
- NHibernate - 對映元件
- NHibernate - 關係
- NHibernate - 集合對映
- NHibernate - 級聯操作
- NHibernate - 延遲載入
- NHibernate - 反向關係
- NHibernate - Load/Get
- NHibernate - LINQ
- NHibernate - 查詢語言
- NHibernate - Criteria 查詢
- NHibernate - QueryOver 查詢
- NHibernate - 原生 SQL
- NHibernate - Fluent Hibernate
- NHibernate 有用資源
- NHibernate - 快速指南
- NHibernate - 有用資源
- NHibernate - 討論
NHibernate - 級聯操作
在本章中,我們將介紹如何使用級聯功能。如果您有一組或多個專案,或者兩個類之間存在關係,例如我們的客戶和訂單,並且存在外部索引鍵關係。如果我們刪除客戶,預設情況下,NHibernate 不會對子物件執行任何操作,因此屬於該客戶的那些物件,我們可能會使訂單成為孤兒。
我們也可能違反外部索引鍵約束,因此我們可以使用級聯的概念。
預設情況下,NHibernate 不會將操作級聯到子物件。
這樣做的原因是,您可能存在這樣的關係:客戶有一個預設的送貨地址,並且該送貨地址由許多不同的客戶共享。
因此,您不希望一定級聯該關係,因為其他客戶仍在引用它。
因此,級聯的整個概念是告訴 NHibernate 如何處理其子實體。
級聯有不同的選項,如下所示:
none - 這是預設值,表示不級聯。
all - 它將級聯儲存、更新和刪除操作。
save-update - 它將級聯儲存和更新操作。
delete - 它將級聯刪除操作。
all-delete-orphan - 這是一個特殊的選項,非常常用,它與 All 相同,除了如果它找到 Delete-orphan 行,它也會刪除這些行。
您可以在 hbm.xml 檔案中指定預設值,因此您可以在該 Hibernate 對映元素上提供預設級聯,或者也可以為特定集合和關係(如多對一)指定它。
讓我們來看一個簡單的級聯示例,讓我們修復程式中的問題,在該問題中,我們必須手動將儲存級聯到訂單,如下面的程式碼所示。
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 檔案,我們可以級聯該多對一關係。
<?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>
因此,如果我們建立一個新訂單,並且有一個新的客戶附加到它,並且我們說儲存該訂單,我們可能希望級聯它。但是,我們可能不希望做的一件事是,如果刪除了一個訂單,則刪除相應的客戶。
因此,在這裡,我們希望執行儲存更新,因此使用 save-update,它將級聯對該客戶的任何儲存或更新。因此,如果我們獲得一個新客戶或如果我們正在更改客戶,它將級聯它。如果它是刪除操作,它不會從資料庫中刪除它。
因此,再次執行我們的應用程式,一切仍然按預期工作。
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,並且您必須考慮您的實體以及它們之間的關係,以確定每個實體以及資料庫中每個關係的適當級聯。