Entity framework 与实体框架相关的实体被EF删除的级联删除

Entity framework 与实体框架相关的实体被EF删除的级联删除,entity-framework,cascading-deletes,Entity Framework,Cascading Deletes,我对实体框架中的删除有问题。简而言之,EF显式地尝试从数据库中删除实体,即使我已明确地将EF配置为在数据库中使用级联删除 我的设计: class Program { static void Main(string[] args) { var context = new Model1Container(); var mainEntity = context.MainEntities.Include("EntityTypeA").SingleOrDefault()

我对实体框架中的删除有问题。简而言之,EF显式地尝试从数据库中删除实体,即使我已明确地将EF配置为在数据库中使用级联删除

我的设计:

class Program
{
   static void Main(string[] args)
   {
      var context = new Model1Container();
      var mainEntity = context.MainEntities.Include("EntityTypeA").SingleOrDefault();
      context.DeleteObject(mainEntity);
      context.SaveChanges();
   }
}
我有三种实体类型,
maintentity
EntityTypeA
EntityTypeB
。EF已配置为在删除
EntityTypeA
EntityTypeB
时使用级联删除。换句话说,如果我删除
maintentity
的一个实例,我希望所有相关的
EntityTypeA
EntityTypeB
实例也被删除。我从不删除
EntityTypeA
EntityTypeB
而不删除它们的父项

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

这就是我的模型的样子:

这些关系具有以下非默认配置:

  • 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();
   }
}
发生了什么

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)
调用SaveChanges时,Entity Framework在数据库中执行以下操作:

exec sp_executesql N'delete [dbo].[EntityTypeA]
where ([Id] = @0)',N'@0 int',@0=1
这会导致外键冲突,因为EntityTypeB的表中有引用EntityTypeA实例的项

问题


为什么即使我已经将EntityFramework配置为使用级联删除,EntityFramework仍会为EntityTypeA实例发出显式删除?如果我删除Include(“EntityTypeA”),它将重新开始工作。

这正是级联删除在EF中的行为方式。在EF设计器中对关系设置级联,指示EF为每个加载的重新分配实体执行
DELETE
语句。它没有说明任何关于数据库中级联删除的

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

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

EF中级联删除的实现很奇怪,效率也很低,但这就是它的行为方式,如果您想使用它,您必须修改应用程序,使其在这种情况下正确运行。

也可以在数据库中的FK约束上设置级联删除,而不是在EF设计器上

以下是SQLServerManagementStudio(SSMS)中有关如何设置级联删除的可视化步骤

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

我在我的博客上对此进行了更深入的讨论:

谢谢你的回复!(当我生成数据库模型sql脚本时,如果我在实体数据模型中启用了CASCADE,则EF会在sql语句中包含ON CASCADE DELETE,因此我认为EF将依赖于此。)(模型的)映像不可用