【问题标题】:(Keep orphans alive) How to map child entity to set parentID property to null on father delete(保持孤儿活着)如何映射子实体以在父亲删除时将 parentID 属性设置为 null
【发布时间】:2015-02-26 13:44:01
【问题描述】:

在 EF Code First 中:我们如何映射子实体以在父删除时将 parentID 属性设置为 null? (让孤儿活着)

例子:

class FullGroup - ID, Name, IEnumerable<Machine>() Machines, etc....

class Machine - ID, Name, virtual FullGroup? (asnullable), int? FullGroupId, etc.....

this.HasOptional(t => t.FullGroup)
                .WithMany(t => t.Machines)
                .HasForeignKey(t => t.FullGroupId); 

我知道当我想删除父亲条目时,如果我只加载父亲并尝试删除它,我会得到一个异常(如果fatherId不可为空)....但如果我还包括(加载) 孩子再尝试删除父亲,事情就行了。 然而,这不是我要找的......

【问题讨论】:

    标签: c# entity-framework ef-code-first


    【解决方案1】:

    如果依赖实体上的外键可以为空(例如您的案例-FullGroupId),Code First 不会对关系设置级联删除。所以你需要配置它,试试这个:

    this.HasOptional(t => t.FullGroup)
                .WithMany(t => t.Machines)
                .HasForeignKey(t => t.FullGroupId).WillCascadeOnDelete(true);
    

    我现在看到了你的更新,是的,如果子实体也被加载到上下文中,它就可以工作,而不仅仅是父实体。有关更多信息,您可以查看此link。 EF 将翻译你想在 sql 命令中执行的删除,如下所示:

    exex sp_executesql N'delete [dbo].[Machines] where ([Id]=@0)',N'@0 int',@0=1
    exex sp_executesql N'delete [dbo].[Machines] where ([Id]=@0)',N'@0 int',@0=2
    exex sp_executesql N'delete [dbo].[Machines] where ([Id]=@0)',N'@0 int',@0=3
    --...
    exex sp_executesql N'delete [dbo].[FullGroups] where ([Id]=@0)',N'@0 int',@0=1
    

    但是,从我之前分享的link(根据您的场景),您可以看到:

    由于内存中没有Machines,所以不会有客户端级联删除,但是数据库应该清理任何 孤立的Machines 因为在 数据库。 运行时(删除FullGroup),发送到数据库的唯一命令是删除FullGroup。数据库级联删除将删除相关机器作为响应。

    因此,如果您在关系中配置级联删除,则无需急切加载子实体,数据库应该会完成这项工作

    【讨论】:

    • 好吧,我不确定这是否改变了,但在 EF4.0 中我也需要加载孩子,当我删除父亲时,否则,它将删除所有孩子(如果我使用cascadeOnDelete)。
    • 你好@Dryadwoods,我已经更新了我的答案。检查最后一部分,这应该可以回答您在评论中暴露的疑问
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    相关资源
    最近更新 更多