(让孤儿活着)如何映射 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.
因此,如果您在关系中配置级联删除,则无需预先加载子实体,数据库应该完成工作
在 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 orphanedMachines
because of the cascade delete defined in the database. When run (delete aFullGroup
), the only command sent to the database is one to delete theFullGroup
. The database cascade delete will delete the related machines in response.
因此,如果您在关系中配置级联删除,则无需预先加载子实体,数据库应该完成工作