(让孤儿活着)如何映射 child 实体以在父亲删除时将 parentID 属性 设置为 null

(Keep orphans alive) How to map child entity to set parentID property to null on father delete

在 EF Code First 中:我们如何映射 child 实体以在父亲删除时将 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 不可为空)....但是如果我还包括(load) children 然后尝试删除父亲,一切正常。 然而,这不是我要找的.....

如果依赖实体上的外键可以为 null(如您的情况 -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(结合你的场景),你可以看到:

Since there are no Machines in memory, there will be no client-side cascade delete, but the database should clean up any orphaned Machines because of the cascade delete defined in the database. When run (delete a FullGroup), the only command sent to the database is one to delete the FullGroup. The database cascade delete will delete the related machines in response.

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