【Entity Framework】如何理解EF中的级联删除

【Entity Framework】如何理解EF中的级联删除

文章目录

  • 【Entity Framework】如何理解EF中的级联删除
    • 一、概述
    • 二、发生级联行为时
      • 2.1/删除主体/父实体
      • 2.2/断开关系
    • 三、发生级联行为的位置
      • 3.1/级联删除被跟踪实体
      • 3.2/数据库中的级联删除
    • 四、级联NULL

一、概述

Entity Framework Core(EF Core)表示使用外键的关系。具有外键的实体是关系中的子实体或依赖实体。此实体的外键值必须与相关主体/父实体的主键值(或替换键值)匹配。

如果删除主体/父实体,则依赖项/子项的外键值将不再匹配任何主体/父实体的主键或替换键。 这是无效状态,将导致在大多数数据库中出现引用约束冲突。

可通过两种方法来避免此引用约束冲突:

  1. 将外键值设置为 null。
  2. 同时删除依赖实体/子实体

第一个选项仅适用于其中外键属性(及其映射到的数据库列)必须可为null的可选关系。

第二个选项适用于任何类型的关系,它被称作"级联删除"。

二、发生级联行为时

当依赖实体/子实体无法再与其当前主体/父实体关联时,需要执行级联删除。发生这种情况的原因可能是主体/父实体已被删除。或者当主体/父实体仍存在,但依赖实体/子实体在再与其关联时。

2.1/删除主体/父实体

本文中使用的实体类

public class Blog
{public int Id{get;set;}public string NameP{get;set;}public IList<Post> Posts{get;}=new List<Post>();
}
public class Post
{public int Id { get; set; }public string Title { get; set; }public string Content { get; set; }public int BlogId { get; set; }public Blog Blog { get; set; }
}

其中Blog是与Post(依赖实体/子实体)的关系中的主体/父实体。Post.BlogId是一个外键属性,其值必须与该文章所属博客中的Blog.Id主键匹配。

按照约定,由于Post.BlogId外键属性是不可为null的,因此该关系被配置为必需的。默认情况下,所需的关系配置为使用级联删除。

删除博客时,所有文章都将被级联删除。

using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e=>.Name).Include(e => e.Posts).First();
context.Remove(blog);
context.SaveChanges();

SaveChanges 以 SQL Server 为例,生成以下 SQL:

CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;SELECT @@ROWCOUNT;
CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

2.2/断开关系

如果不删除博客,而是断开每篇文章与其博客之间的关系。为此,可将每篇文章的引用导航Post.Blog设置为null:

using var context= new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
foreach(var post in blog.Posts)
{post.Blog = null;
}
context.SaveChanges();

还可通过从 Blog.Posts 集合导航中删除每篇文章内容来断开关系:

using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e.Posts).First();
blog.Posts.Clear();
context.SaveChanges();

无论哪种情况,结果都一样:没有删除博客,但是删除了不再与任何博客关联的文章:

SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

删除不再与任何主体/依赖实体关联的实体这一行为被称作“删除孤立项”。

级联删除和删除孤立项时密切相关的。当断开与所需的主体/父实体之间的关系时,两者都将导致删除依赖实体/子实体。对于级联删除,由于主体/父实体本身已删除,因此发生了这种断开。对于孤立项,主体/父实体仍然存在,但不再与依赖实体/子实体相关。

三、发生级联行为的位置

可将级联行为应用于:

  • 当前DbContext跟踪的实体
  • 数据库中尚未加载到上下文中的实体

3.1/级联删除被跟踪实体

EF Core 始终将配置的级联行为应用于跟踪的实体。 这意味着如上面的示例所示,如果应用程序将所有相关的依赖实体/子实体加载到 DbContext 中,则无论如何配置数据库,都将正确应用级联行为。

3.2/数据库中的级联删除

许多数据库系统还提供在数据库中删除实体时触发的级联行为。使用EnsureCreated或EF Core迁移创建数据库时,EF Core会根据EF Core模型中的级联删除行为来配置这些行为。

CREATE TABLE [Posts] ([Id] int NOT NULL IDENTITY,[Title] nvarchar(max) NULL,[Content] nvarchar(max) NULL,[BlogId] int NOT NULL,CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE
);

请注意,定义博客和文章之间关系的外键约束是用 ON DELETE CASCADE 配置的。

如果我们知道数据库是这样配置的,那么我们可以删除博客,而无需先加载文章,数据库将负责删除与此博客相关的所有文章。 例如:

using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).First();
context.Remove(blog);
context.SaveChanges();

四、级联NULL

可选关系将可为 null 的外键属性映射到可为 null 的数据库列。 这意味着当删除当前主体/父实体或断开与依赖实体/子实体的关系时,可将外键值设置为 NULL。

让我们再看一下发生级联行为时的示例,但这次可选关系由可为null的Post.BlogId外键属性表示:

public int? BlogId { get; set; }

删除每篇文章的相关博客时,该文章的外键属性将设置为 NULL。 例如,此代码与之前的代码相同:

using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
context.Remove(blog);
context.SaveChanges();

当删除可选关系中的主体/父实体时,数据库也可配置为级联 NULL。 但是,与在数据库中使用级联删除相比,这种情况要少得多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/13734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3 路由跳转 携带参数

实现功能&#xff1a;页面A 跳转到 页面B&#xff0c;携带参数 路由router.ts import { createRouter, createWebHistory } from "vue-router";const routes: RouteRecordRaw[] [{path: "/demo/a",name: "aa",component: () > import(&quo…

x264 码率控制原理:x264_ratecontrol_start 函数

x264_ratecontrol_start 函数 函数原理 函数功能:编码一帧之前,为当前帧选择一个量化 QP,属于帧级别码率控制;这对于控制视频质量和文件大小至关重要。通过调整QP,编码器可以在保持视频质量的同时,尽可能减小输出文件的大小。函数参数:x264_t *h: 编码器上下文结构体指…

十七、个人信息出境标准合同的具体内容有哪些?

根据《标准合同办法》第六条&#xff0c;标准合同应当严格按照网信办制定版本订立&#xff0c;个人信息处理者可以与境外接收方约定其他条款&#xff0c;但不得与标准合同相冲突。 根据《标准合同办法》附件&#xff0c;目前版本的标准合同内容主要包括&#xff1a; 1. 个人信…

Flutter 中的 TextButton 小部件:全面指南

Flutter 中的 TextButton 小部件&#xff1a;全面指南 在Flutter的世界里&#xff0c;TextButton是一个基础的小部件&#xff0c;用于创建只包含文本的按钮。它通常用于对话框、表单以及需要强调主要操作的界面。本文将为您提供一个全面的指南&#xff0c;帮助您了解如何使用T…

地信遥感测绘电子书

《地理信息系统概论》&#xff0c;黄杏元&#xff0c;马劲松编著&#xff0c;第三版&#xff0c;高等教育出版社&#xff0c;2008年 《地理信息系统》&#xff08;第二版&#xff09;汤国安&#xff0c;赵牡丹&#xff0c;杨昕等编&#xff0c;高等教育出版社&#xff0c;2010…

【stm32/CubeMX、HAL库】嵌入式实验五:定时器(2)|PWM输出

参考&#xff1a; 【【正点原子】手把手教你学STM32CubeIDE开发】 https://www.bilibili.com/video/BV1Wp42127Cx/?p13&share_sourcecopy_web&vd_source9332b8fc5ea8d349a54c3989f6189fd3 《嵌入式系统基础与实践》刘黎明等编著&#xff0c;第九章定时器&#xff0c…

8操作系统定义、分类及功能+设备管理+作业管理 软设刷题 软考+

操作系统定义、分类及功能设备管理作业管理 知识点1-55-1010-1515-2020-2525-3030-35 刷题操作系统定义、分类及功能1-55-1010-15作业管理1-5设备管理1-55-10 知识点 1-5 1 嵌入式操作系统的特点&#xff1a; 1.微型化&#xff0c;从性能和成本角度考虑&#xff0c;希望占用的…

145.栈和队列:删除字符串中的所有相邻重复项(力扣)

题目描述 代码解决 class Solution { public:string removeDuplicates(string s) {// 定义一个栈来存储字符stack<char> st;// 遍历字符串中的每一个字符for(int i 0; i < s.size(); i){// 如果栈为空或栈顶字符与当前字符不相同&#xff0c;则将当前字符入栈if(st.e…

Jenkins的Pipeline流水线

目录 前言 流水线概念 什么是流水线 Jenkins流水线 pipeline node stage step 创建一个简单的流水线 创建Pipeline项目 选择模板 测试 前言 提到 CI 工具&#xff0c;首先想到的就是“CI 界”的大佬——Jenkjns,虽然在云原生爆发的年代,蹦出来了很多云原生的 CI 工具…

Hive的窗口函数

定义&#xff1a; 聚合函数是针对定义的行集(组)执行聚集,每组只返回一个值.如sum()、avg()、max() 窗口函数也是针对定义的行集(组)执行聚集,可为每组返回多个值.如既要显示聚集前的数据,又要显示聚集后的数据.步骤&#xff1a; 1.将记录分割成多个分区. 2.在各个分区上调用窗…

word-表格疑难杂症诊治

一、用表格进行排版图片、制作公文头 可以在插入图片时固定列宽 二、表格中的疑难杂症 问题一&#xff1a;表格超过页面&#xff0c;右侧文字看不见 解决&#xff1a;表格窗口-布局-自动调整-根据窗口自动调整表格 问题二&#xff1a;表格底部文字被遮挡 解决&#xff1a;布…

ArcGIS Maps SDK for JS:使用queryFeatures方法查询 FeatureLayer 中符合条件的要素

文章目录 方式一&#xff1a;使用featureLayer.createQuery()方法方式二&#xff1a;使用 Query 构造函数方式三&#xff1a;简化写法 要想查询FeatureLayer 图层中满足某些条件的要素&#xff0c;可以使用ArcGIS API for JavaScript 提供的queryFeatures() 方法和 Query 对象进…

【linux】yumvim工具理解使用

目录 Linux 软件包管理器 yum 关于 rzsz 注意事项 查看软件包 Linux开发工具 Linux编辑器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 简单vim配置 配置文件的位置 sudo提权 Linux 软件包管理器 yum 1.yum是什么&#xff1…

攻防世界---web---warmup

1、题目描述 2、查看源码&#xff0c;发现有个source.php 3、访问该文件&#xff0c;得到这一串代码 4、分析代码 5、访问hint.php&#xff0c;提示flag在ffffllllaaaagggg这个文件下 6、构造payload ?filesource.php?/../../../../../../ffffllllaaaagggg

Fitting Parameterized Three-Dimensional Models to Images

摘要 基于模型的识别和运动跟踪依赖于解决投影和模型参数&#xff0c;使其最佳适应匹配的2D图像特征的3D模型的能力。本文将当前的参数求解方法扩展到处理具有任意曲面和任意数量的内部参数&#xff08;表示关节、可变尺寸或表面变形&#xff09;的对象。开发了数值稳定化方法…

懒人网址导航页 search.html SQL注入漏洞复现

0x01 产品简介 懒人网址导航系统是一种智能化的网址导航平台,旨在帮助用户快速找到所需的网址和资源。该系统提供了智能化的网址搜索和推荐功能,能够根据用户的搜索习惯和偏好推荐相关的网址和资源。同时,系统还提供了网址分类、网址收藏和网址分享等功能,方便用户管理和共…

git常见的18条指令

使用git的时候有没有遗忘指令的情况呢&#xff1f;小编替大家整理出来了18条常用的指令&#xff0c;大家赶紧收藏起来吧&#xff01; gti常见的18条指令 序号指令含义1git init初始化一个仓库2git clone [url]克隆一个仓库3git add [file]添加文件到暂存区4git commit -m "…

简易Docker磁盘使用面板Doku

这个项目似乎有 1 年多没更新了&#xff0c;最后发布版本的问题也没人修复&#xff0c;所以看看就行&#xff0c;不建议安装 什么是 Doku &#xff1f; Doku 是一个简单、轻量级的基于 Web 的应用程序&#xff0c;允许您以用户友好的方式监控 Docker 磁盘使用情况。Doku 显示 D…

easyexcel导出动态标题,以及动态设置下拉选择,并设置下拉选择校验

目录 1.说明 2.示例 3.总结 1.说明 平时使用easyexcel进行导出时&#xff0c;标题的名字通过在表的实体类上添加注解的方式进行实现&#xff0c;然后传入表的实体类的集合进行下载即可。 有这么一个需求&#xff0c;用户可以自定义导出的模板&#xff0c;也就是说导出的模板…

南京沁恒微USB HUB CH334/CH335多种封装规格选择,外围简单,价格还美丽

概述&#xff1a; CH334 和 CH335 是符合 USB2.0 协议规范的 全速&#xff0c;下行端口支持 USB2.0 高速 480Mbps 个 TT 分时调度 4 个下行端口&#xff09;&#xff0c;还支持高性能的 工业级设计&#xff0c;外围精简&#xff0c;可应用于计算机和工控机主板 特点&#xff1…