NHibernate使用delete cascade从父集合中删除子集合

本文关键字:集合 删除 子集合 使用 delete cascade NHibernate | 更新日期: 2023-09-27 17:49:01

我有两个名为Country和City的简单实体。

public class Country : Entity
{
    public Country()
    {
        Cities = new List<City>();
    }
    public virtual string Name { get; set; }
    public virtual IList<City> Cities { get; set; }
}
public class City : Entity
{
    public virtual Country Country { get; set; }
    public virtual string Name { get; set; }
}

使用的数据库是SQL Server,并且City有一个指向Country的外键,具有级联删除功能。

我正在使用Fluent NHibernate,这是关系的映射配置:

public CountryMap()
    {
            Id(x => x.Id, "IdCountry").GeneratedBy.Identity();
            Map(x => x.Name).Not.Nullable().Length(50);
            HasMany(x => x.Cities).KeyColumn("IdCountry").ForeignKeyConstraintName("FK_Cities_Countries")
                .Not.KeyNullable().Cascade.AllDeleteOrphan().ExtraLazyLoad();
            Table("Countries");
    }
public CityMap()
    {
            Id(x => x.Id, "IdCity").GeneratedBy.Identity();
            Map(x => x.Name).Not.Nullable().Length(50);
            References(x => x.Country, "IdCountry").ForeignKey("FK_Cities_Countries")
                .Not.Nullable().Not.Insert().Not.Update().Cascade.All().LazyLoad();

            Table("Cities");
    }

所有工作正常,但删除一个国家后,城市仍然在父集合,我希望从该集合中删除的城市。(如EF)

我发现让它工作的唯一方法是刷新会话(Clear, Evict…)

NHibernate使用delete cascade从父集合中删除子集合

手动删除集合项不是解决方案。它实际上破坏了cascading的特性。

如果我们确实有映射 Cascade.AllDeleteOrphan() ,我们应该期望删除将删除 -不需要做更多的删除。只是…NHibernate不关心清除内存中的集合(app server/application)

如果您正在寻找持久,稳定,坚实的解决方案,我强烈建议:

拆分读写操作

我们现有的框架(比如Web API)正在帮助我们朝这个方向发展。我们应该创建一组操作:

  • put, post, delete…处理客户要求修改资料
  • 得到……通过ID或Criteria (Find())
  • 检索数据
这些操作中的每一个都应该有自己的会话,自己的事务,并且应该代表工作单元。要么全有,要么全无。要么操作成功并且所有操作都被持久化,要么不(回滚)

这将有助于我们的应用程序的成功和长期发展。我们分开。我们关心的是

1) DELETE, UPDATE或INSERT (或围绕一些根实体的更多操作,可以在这里看到更多)。2)我们做READ操作-期望只有SELECT操作,因此使用最新的数据。还要检查这个,包括注释

虽然这可能有点超出范围,但这里引用9.8。异常处理文档也是线索:

…如果ISession抛出异常,您应该立即回滚事务,调用ISession.Close()并丢弃session实例。会话的某些方法不会使会话保持一致状态…

我想证明,操作(session, transaction)应该只有一个目标(WRITE, READ)并且尽可能短

对于这种映射,最简单的方法是从Country集合中删除City并保存Country。使用级联,城市将被删除,集合将处于您想要的状态。