2011-03-27 151 views
26

我在实体框架中删除了一个问题。简而言之,EF明确地试图从数据库中删除一个实体,即使我已经明确地配置了EF来使用数据库中的级联删除。使用实体框架级联删除 - 由EF删除的相关实体

我的设计:

我有三个实体类型,MainEntityEntityTypeAEntityTypeB。在删除EntityTypeAEntityTypeB时,EF已配置为使用级联删除。换句话说,如果我删除了一个MainEntity的实例,我希望所有相关的EntityTypeAEntityTypeB实例也被删除。我从不删除EntityTypeAEntityTypeB而不删除其父母。

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

这是我的模型是什么样子:

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

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

的关系EntityTypeA -> EntityTypeBOnDelete: 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,实体框架会发生什么

在数据库中执行以下操作:

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

这将导致外键冲突,因为在EntityTypeB的表引用EntityTypeA实例项目。

问题

为什么实体框架的问题一个明确的删除EntityTypeA的情况下,即使我已经配置实体框架使用级联删除?如果我删除包含(“EntityTypeA”),它会再次开始工作。

+10

图像(模型的)是不可用的 – flipchart 2014-02-25 06:27:08

回答

41

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

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

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

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

+2

感谢您的答复! (当我生成我的数据库模型sql脚本时,如果我在实体数据模型中启用级联,则EF在SQL语句中包含ON CASCADE DELETE,因此我担心EF会依赖于此)。 – Nitramk 2011-03-27 11:45:57

5

除了在EF设计器上,还可以在数据库中的FK Constraints上设置级联删除。

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

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

enter image description here

我更深入地在我的博客讨论这个问题:Entity Framework Cascading Deletes; Set it from the database.