【问题标题】:Deletion of one-to-zero or one child record not working删除一对零或一个子记录不起作用
【发布时间】:2019-06-26 10:06:45
【问题描述】:

我正在尝试映射几个表,其中 Bar 中的主键是 Foo 的外键,即 1..0:1 关系。

我的映射如下所示:

class FooMapping : ClassMap<Foo>
{
    public FooMapping()
    {
        Table("Foo");

        Id(x => x.Id).Column("ID");

        HasOne(x => x.Bar).Cascade.All();
    }
}

class BarMapping : ClassMap<Bar>
{
    public BarMapping()
    {
        Table("Bar");

        Id(x => x.FooId).GeneratedBy.Foreign("Foo");

        HasOne(x => x.Foo).Constrained();
    }
}

问题是,当我尝试通过设置Foo.Bar = nullBar.Foo = null 来删除Bar 的实例时,记录不会从数据库中删除。

我错过了什么?

【问题讨论】:

  • 它是否删除了从 Foo 到 Bar 的引用(将数据库中的列设置为 null)?
  • Foo 表中没有对 Bar 的引用。就像我说的,Bar 中的主键也是 Foo 的外键。

标签: nhibernate orm fluent-nhibernate


【解决方案1】:

所以基本上问题是您在Foo 的映射中使用Cascade.All()。 而不是你应该使用Cascade.AllDeleteOrphan()

Cascade.All

当一个对象被保存/更新/删除时,检查关联并保存/更新/删除所有找到的对象。

Cascade.AllDeleteOrphan

当一个对象被保存/更新/删除时,检查关联并保存/更新/删除所有找到的对象。除此之外,当一个对象从关联中移除并且不与另一个对象关联(孤立)时,也将其删除。

【讨论】:

  • 除非我遗漏了什么,否则 HasOne 上没有定义 Cascade.AllDeleteOrphan
  • @SimonMorgan 看着这个:nhibernate.jira.com/browse/NH-1262 一对一的关系应该有它。您使用的是哪个版本的 NHibernate?
  • @SimonMorgan 也可能对您有所帮助:stackoverflow.com/a/13867594/6870620
  • 虽然 NHibernate 似乎在一对一关系上支持 AllDeleteOrphan,但 Fluent NHibernate 尚未添加支持。 2017 年有一个拉取请求,但被忽略了。
  • 我已经尝试了从该答案链接的 URL 中的映射,但我仍然遇到相同的问题,即删除关系时记录没有被删除。
【解决方案2】:

通过使用 HasMany 和 Cascade.AllDeleteOrphan 建立这种关系,还有其他肮脏的解决方案。

class FooMapping : ClassMap<Foo>
{
    public FooMapping()
    {
       Table("Foo");
       Id(x => x.Id).Column("ID");
       HasMany(x => x.Bar).KeyColumn("FooId").Cascade.AllDeleteOrphan();
    }
}

【讨论】:

  • 我无法让它工作。我不确定 KeyColumn 期望在哪里找到“FooId”列,但指向 Foo 的外键是 Bar 的主键。即使我似乎告诉它键列的名称,它也会出错,因为它试图最初将值设置为 null ,这是不允许的,因为它是主键。链接 .Not.Nullable() 没有区别。
  • 您可以尝试将其与选项 Inverse() 一起使用。 Bar 应该生成删除语句,而不是设置 pk 的 null 值。
  • 仍然无法正常工作。就像它试图找出外键但弄错了(似乎认为某处涉及“Foo_id”列),即使我在关系的双方都正确设置了我的 ID。
  • 我的最后一个想法,也许你可以尝试覆盖生成的 Bar pk 名称的默认名称,例如Id(x => x.Food,"ColumnName").
  • 谢谢,但就像我说的,我已经正确映射了 ID 列。我很确定零对一或零关系(可以删除)是不可能使用 Fluent NHibernate 开箱即用的。我使用 dnSpy 破解了程序集以添加对 Cascade.AllDeleteOrphan 的支持,并且它在没有任何破解的情况下运行良好。自 2017 年以来,Fluent NHibernate PR 就一直放在 GitHub 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
相关资源
最近更新 更多