删除一对零或一个子记录不起作用

Posted

技术标签:

【中文标题】删除一对零或一个子记录不起作用【英文标题】: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 的外键。 【参考方案1】:

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

Cascade.All

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

Cascade.AllDeleteOrphan

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

【讨论】:

除非我遗漏了什么,否则 HasOne 上没有定义 Cascade.AllDeleteOrphan @SimonMorgan 看着这个:nhibernate.jira.com/browse/NH-1262 一对一的关系应该有它。您使用的是哪个版本的 NHibernate? @SimonMorgan 也可能对您有所帮助:***.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 上。

以上是关于删除一对零或一个子记录不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 EF7 映射一对零或一

从核心数据中删除记录不起作用?

实体框架可选的一对一关系不起作用

Coredata,级联删除不起作用

通过 CKSubscription 观察 CKRecord 删除不起作用

删除 Kafka StateStore 中的记录不起作用(在 .delete(key) 上抛出 NullPointerException)