我一直在尋找的答案,我的問題了幾天建造和我試過最提示/答案,甚至通過看刪除從集合項百行由nHibernate生成的日誌行,但我找不到一種方法來讓我的映射工作..nHiberante仍然拒絕生成任何刪除語句,當它被要求SaveOrUpdate。(流利)NHibernate的不是在業務對象是由合同轉換
我有三個獨立的實體,人,房子和房......在現實世界中,每個人都會有一個房子,每間房子可以有多個房間,房子和房間之間的映射是一個一對多的預計,我希望人與樓之間有一個一對一映射,然後我就一口流利NHibernate的維基說,這是真的讀了很多(人)-to-一個(居),因爲沒有東西在數據庫級別停止多共享同一房屋的人。我想這是有道理的,所以我有我的數據庫架構和類圖設計如下:
CREATE TABLE [dbo].[Person](
[PersonId] [int] IDENTITY(1,1) NOT NULL,
[HouseId] [int] NOT NULL
)
CREATE TABLE [dbo].[House](
[HouseId] [int] IDENTITY(1,1) NOT NULL,
[HouseName] [varchar](500) NOT NULL
)
CREATE TABLE [dbo].[Room](
[RoomId] [int] IDENTITY(1,1) NOT NULL,
[HouseId] [int] NOT NULL
)
HouseId on [Person] and [Room] are both foreign keys referencing HouseId from [House] table
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Table("Person")
Id (x=>x.Id).Column("PersonId").GeneratedBy.Identity().UnsavedValue(0);
Reference(x=>x.House).Column("HouseId").ForeignKey("HouseId").Not.LazyLoad().Cascade.All();
}
}
public class HouseMap : HouseMap<Room>
{
public RoomMap()
{
Table("House")
Id (x=>x.Id).Column("HouseId").GeneratedBy.Identity().UnsavedValue(0);
HasMany(x => x.Persons)
.KeyColumn("HouseId")
.Not.LazyLoad()
.Cascade.AllDeleteOrphan().Inverse();
HasMany(x => x.Rooms)
.KeyColumn("HouseId")
.Not.LazyLoad()
.Cascade.AllDeleteOrphan().Inverse();
}
}
public class RoomMap : ClassMap<Room>
{
public RoomMap()
{
Table("Room")
Id (x=>x.Id).Column("RoomId").GeneratedBy.Identity().UnsavedValue(0);
Reference(x=>x.House).Column("HouseId").ForeignKey("HouseId").Not.LazyLoad().Cascade.All();
}
}
類衆議院分別持有型人與房的兩個列表,並Person類和客房都擁有一個參考回衆議院對象。
因此,我創建了一個House實例並設置了它的兩個子列表Person(one 1)和Room(multiple rooms),並且還將Person/Rooms的屬性鏈接回House ..並使用session.SaveOrUpdate保存這個人一切正常。
然後我嘗試檢索Person的實例,並從Person.House.List中刪除一個房間,並將room.House設置爲null以完全中斷引用,然後使用session.SaveOrUpdate再次保存該人(我們稱之爲人A),nHibernate正確地生成刪除語句,刪除孤兒室,它沒有鏈接到它的父母家更多..迄今爲止好...
這裏是我的問題開始的地方...在我的應用程序,我需要的對象者轉換爲PersonContract,然後將其發送給客戶端,客戶端刪除從PersonContract.HouseContract一個roomContract和發送PersonContract複印件背面的能力。注意PersonContract,也真不是雙邊的參考,即PersonContract具有HouseContract的一個屬性和HouseContract只包含RoomContract的列表,以便HouseContract不保留PersonContract的列表,並RoomContract沒有HouseContract財產。
然後在服務器端,我將PersonContract轉換回Person對象,並且轉換器負責創建Person,Room和Houses的所有新實例,並設置它們的ID並在它們之間構建所有的雙向引用。
問題是......當我在Person對象上使用session.SaveOrUpdate(在合同轉換後)時,nHibernate似乎忽略了一個房間已從集合中刪除的事實,但它更新或插入作業..
我仔細檢查了我的合同轉換器,以確保所有的屬性/引用/ ID設置正確,它看起來與上面的人A完全一樣的副本......但我不明白爲什麼nHibernate在這裏沒有做這份工作。
我已經撤消了對人/房/房子了equals和GetHashCode返回其ID。
我觀察到的另一個事實是,當我使用session.SaveOrUpdate轉換後的Person對象上,NHibernate的是產生大量更新語句,即使價值並沒有什麼變化,它看起來好像NHibernate的是不知道的狀態的持久化Person對象,所以選擇通過使用Id標識來更新所有內容...
我對nHibernate相當陌生...所以請讓我知道如果我做一些可怕的錯誤在這裏:)
更新:如果我從一到多的房子和房間之間的映射刪除反,然後NHibernate的會集中移除室的內部ID爲NULL ......不是在所有未移除的房間,但我真的希望它從數據庫中刪除孤立的客房越好..
更新2:session.Merge上的人在工作(SaveOrUpdate沒有)...雖然我不明白爲什麼..