使用实体框架级联删除 - EF 删除的相关实体 [英] Cascading deletes with Entity Framework - Related entities deleted by EF

查看:44
本文介绍了使用实体框架级联删除 - EF 删除的相关实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在实体框架中遇到删除问题.简而言之,即使我已经明确地将 EF 配置为在数据库中使用级联删除,EF 也会显式地尝试从数据库中删除实体.

I have an issue with deletion in Entity Framework. In short, EF explicitly tries to delete an entity from the database even though I've explcitly configured EF to use cascading deletes in the database.

我的设计:

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

I have three entity types, MainEntity, EntityTypeA and EntityTypeB. EF has been configured to use cascade deletion when deleting EntityTypeA and EntityTypeB. In other words, if I delete an instance of MainEntity, I want all related EntityTypeA and EntityTypeB instances to be deleted as well. I never delete EntityTypeA or EntityTypeB without also deleting their parent.

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

My problem is that EF explictly issues a DELETE statement for EntityTypeA, which causes my application to crash.

这是我的模型的样子:

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

The relations have the following non-default config:

  • MainEntity ->EntityTypeA OnDelete:级联
  • MainEntity ->EntityTypeB OnDelete:级联

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

When I call SaveChanges, Entity Framework executes the following in the database:

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

这会导致外键冲突,因为 EntityTypeB 的表中存在引用 EntityTypeA 实例的项目.

This causes an foreign key violation, because there are items in EntityTypeB's table referencing EntityTypeA instances.

问题

即使我已将实体框架配置为使用级联删除,为什么实体框架仍为 EntityTypeA 的实例发出显式删除?如果我删除 Include("EntityTypeA") 它会再次开始工作.

Why does Entity Framework issue an explicit delete for the instance of EntityTypeA even though I've configured Entity Framework to use cascading deletes? If I remove the Include("EntityTypeA") it starts working again.

推荐答案

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

This is exactly how cascading deletes behaves in EF. Setting Cascade on a relation in EF designer instructs EF to execute DELETE statement for each loaded realated entity. It doesn't say anything about ON CASCADE DELETE in the database.

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

Setting Cascade deletion when using EF needs two steps:

  • 在 EF 设计器中设置 Cascade 关系.此指示上下文必须在删除父实体之前删除所有加载的相关实体.如果这没有发生,EF 将抛出异常,因为内部状态将检测到加载的子项与任何现有的父实体无关,即使关系是必需的.我不确定这是在执行父实体的删除语句之前还是之后发生的,但没有区别.EF 在执行修改后不会重新加载相关实体,因此它根本不知道数据库中触发的级联删除.
  • 在数据库中的关系上设置ON CASCADE DELETE.这将指示 SQL 删除所有在删除父项时未加载到上下文的相关记录.
  • Set Cascade on relation in EF designer. This instruct context that all loaded related entities must be deleted prior to deletion of the parent entity. If this doesn't happen EF will throw exception because internal state will detect that loaded childs are not related to any existing parent entity even the relation is required. I'm not sure if this happens before execution of delete statement of the parent entity or after but there is no difference. EF doesn't reload related entities after executing modifications so it simply doesn't know about cascade deletes triggered in the database.
  • Set ON CASCADE DELETE on relation in database. This will instruct SQL to delete all related records which were not loaded to context in the time of deleting the parent.

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

The implementation of cascade deletes in EF is strange and quite inefficient but this is how it behaves and if you want to use it, you must modify your application to behaves correctly in this scenario.

这篇关于使用实体框架级联删除 - EF 删除的相关实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆