(fluent)当业务对象由合同转换器构造时,nHibernate不会从集合中删除项

(fluent)当业务对象由合同转换器构造时,nHibernate不会从集合中删除项,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,几天来,我一直在搜索我的问题的答案,我尝试了大多数提示/答案,甚至查看了nHibernate生成的数百行日志,但我找不到一种方法让我的映射工作起来。。当要求nHiberante保存或更新时,它仍然拒绝生成任何delete语句 我有三个独立的实体,人,房子和房间。。。实际上,每个人都有一所房子,每个房子都可以有多个房间,房子和房间之间的映射是预期的一对多,我想要一个人和房子之间的一对一映射,然后我在流畅的nHibernate维基上读到,这真的是一个多(人)-一(房子)因为在数据库级别没有任何东西可

几天来,我一直在搜索我的问题的答案,我尝试了大多数提示/答案,甚至查看了nHibernate生成的数百行日志,但我找不到一种方法让我的映射工作起来。。当要求nHiberante保存或更新时,它仍然拒绝生成任何delete语句

我有三个独立的实体,人,房子和房间。。。实际上,每个人都有一所房子,每个房子都可以有多个房间,房子和房间之间的映射是预期的一对多,我想要一个人和房子之间的一对一映射,然后我在流畅的nHibernate维基上读到,这真的是一个多(人)-一(房子)因为在数据库级别没有任何东西可以阻止多人共享同一个房子。我想这是有道理的,所以我的数据库模式和类映射设计如下:

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();
        }
    }
创建表[dbo].[Person](
[PersonId][int]标识(1,1)不为空,
[HouseId][int]不为空
)
创建表[dbo].[House](
[HouseId][int]标识(1,1)不为空,
[HouseName][varchar](500)不为空
)
创建表[dbo].[Room](
[RoomId][int]标识(1,1)不为空,
[HouseId][int]不为空
)
[Person]和[Room]上的HouseId都是引用[House]表中HouseId的外键
公共类PersonMap:ClassMap
{
公众人物地图()
{
表(“人”)
Id(x=>x.Id).Column(“PersonId”).GeneratedBy.Identity().UnsavedValue(0);
引用(x=>x.House).Column(“HouseId”).ForeignKey(“HouseId”).Not.LazyLoad().Cascade.All();
}
}
公共类房屋地图:房屋地图
{
公共房间地图()
{
表(“房屋”)
Id(x=>x.Id).Column(“HouseId”).GeneratedBy.Identity().UnsavedValue(0);
有很多人(x=>x人)
.KeyColumn(“HouseId”)
.Not.LazyLoad()
.Cascade.AllDeleteOrphan().Inverse();
有许多(x=>x个房间)
.KeyColumn(“HouseId”)
.Not.LazyLoad()
.Cascade.AllDeleteOrphan().Inverse();
}
}
公共类RoomMap:ClassMap
{
公共房间地图()
{
桌子(“房间”)
Id(x=>x.Id).Column(“RoomId”).GeneratedBy.Identity().UnsavedValue(0);
引用(x=>x.House).Column(“HouseId”).ForeignKey(“HouseId”).Not.LazyLoad().Cascade.All();
}
}
类House分别保存类型Person和Room的两个列表,类Person和Room都保存对House对象的引用

因此,我创建了House的一个实例,并设置了它的两个子列表Person(一个1)和Room(多个房间),还将Person/Room的属性链接回House..并使用session.SaveOrUpdate保存Person,这一切都很好

然后我尝试检索Person的一个实例,并从Person.House.List中删除一个房间,并将room.House设置为null以完全中断引用,然后使用session.SaveOrUpdate再次保存该人(我们称之为Person a),nHibernate正确生成delete语句以删除不再链接到其父房间的孤立房间。。到目前为止还不错

在我的应用程序中,我需要将对象Person转换为PersonContract,然后将其发送给客户端,客户端可以从PersonContract.HouseContract中删除roomContract并将PersonContract的副本发送回。注:在PersonContract中,没有双边参考,即PersonContract有一个HouseContract属性,HouseContract仅包含一个RoomContract列表,因此HouseContract不保留PersonContract列表,RoomContract没有HouseContract属性

然后在服务器端,我将PersonContract转换回Person对象,转换器负责创建Person、Room和House的所有新实例,设置它们的ID,并在它们之间构建所有双边引用

问题是。。。当我在Person对象上使用session.SaveOrUpdate时(在合同转换之后),nHibernate似乎忽略了一个事实,即房间已从集合中移除,但它很好地完成了更新或插入工作

我已经仔细检查了我的合同转换器,以确保所有属性/引用/ID都正确设置,并且它看起来与上面的人A完全相同……但我不明白为什么nHibernate不在这里工作

我已经覆盖了Person/Room/House上的Equals和GetHashCode以返回其id

我观察到的另一个事实是,当我在转换后的Person对象上使用session.SaveOrUpdate时,nHibernate正在生成大量的Update语句,即使值没有真正更改,看起来nHibernate似乎不知道持久化Person对象的状态,所以选择通过使用Id标识它来更新所有内容

我是nHibernate的新手……所以如果我在这里犯了什么可怕的错误,请告诉我:)

更新:如果我从房屋和房间之间的一对多映射中删除了Inverse,那么nHibernate会将删除房间的房屋ID设置为NULL…这比根本不删除房间要好,但我确实希望它从DB中删除孤立的房间


更新2:会话。人员合并正在工作(SaveOrUpdate不工作)…尽管我不知道原因。

尝试在事务中包装您的保存/更新:

using (ITransaction transaction = session.BeginTransaction())
{
    session.Save(SomeObject);
    transaction.Commit();
}