entity framework级联删除 – 由EF删除的相关实体

我在entity framework中删除了一个问题。 简而言之,EF显式地试图从数据库中删除一个实体,尽pipe我已经明确地configuration了EF来使用数据库中的级联删除。

我的devise:

我有三个实体types, MainEntityEntityTypeAEntityTypeB 。 在删除EntityTypeAEntityTypeB时,EF已被configuration为使用级联删除。 换句话说,如果我删除了MainEntity一个实例,我想要删除所有相关的EntityTypeAEntityTypeB实例。 我从不删除EntityTypeAEntityTypeB而不删除他们的父母。

我的问题是EF显式地为EntityTypeA发出DELETE语句,这会导致我的应用程序崩溃。

这就是我的模型的样子:

关系有以下非默认configuration:

  • MainEntity -> EntityTypeA OnDelete: Cascade
  • MainEntity -> EntityTypeB OnDelete: Cascade

关系EntityTypeA -> EntityTypeB具有OnDelete: None

数据库内容

 INSERT INTO MainEntities (Name) values ('Test') insert into EntityTypeA (MainEntityID) VALUES (1) insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1) insert into EntityTypeB (MainEntityID, EntityTypeAId) VALUES (1, 1) 

我的代码:

 class Program { static void Main(string[] args) { var context = new Model1Container(); var mainEntity = context.MainEntities.Include("EntityTypeA").SingleOrDefault(); context.DeleteObject(mainEntity); context.SaveChanges(); } } 

怎么了

当我调用SaveChanges时,entity framework在数据库中执行以下操作:

 exec sp_executesql N'delete [dbo].[EntityTypeA] where ([Id] = @0)',N'@0 int',@0=1 

这会导致外键违例,因为在EntityTypeB的表中引用了EntityTypeA实例中的项目。

为什么entity framework为EntityTypeA的实例发出一个明确的删除,即使我已经configurationentity framework使用级联删除? 如果我删除包含(“EntityTypeA”)它再次开始工作。

这正是级联删除在EF中的行为方式。 在EFdevise器中为关系设置级联指示EF为每个加载的相关实体执行DELETE语句。 它没有ON CASCADE DELETE在数据库中的任何内容。

使用EF设置级联删除需要两个步骤:

  • 在EFdevise器中设置级联关系。 这指示上下文,在删除父实体之前必须删除所有加载的相关实体。 如果没有发生这种情况,EF会抛出exception,因为内部状态会检测到已加载的子项与任何现有的父实体都没有关系,即使这个关系是必需的。 我不确定这是否在执行父实体的删除语句之前或之后发生,但没有区别。 EF不会在执行修改后重新加载相关实体,因此它不知道数据库中触发的级联删除。
  • 在数据库中设置ON CASCADE DELETE关系。 这将指示SQL删除在删除父项时未加载到上下文的所有相关logging。

EF中级联删除的实现很奇怪,而且效率很低,但是这就是它的行为,如果你想使用它,你必须在这个场景中修改你的应用程序的行为。

而不是EFdevise师,也可以在数据库中的FK Constraints上设置级联删除。

以下是Sql Server Management Studio(SSMS)关于如何设置级联删除的可视步骤。

注意完成后,在尝试删除之前,不要忘记更新edmx对数据库。

在这里输入图像描述

我在我的博客上更深入地讨论这个问题: entity framework级联删除; 从数据库中设置它。