12-5. 自动删除相关联实体

问题

当一个实体被删除时,你想自动删除它相关联的实体

解决方案

假设你有一个表结构由一个course (科目), course 的classes (课程),以及enrollment (登记学生选课),如 Figure 12-5所示:.

Figure 12-5. The Course, Class, and Enrollment tables in our database

由上述表生成一个模型,如下图Figure 12-6所示:.

Figure 12-6. A model with the Course, Class, and Enrollment entities and their associations

当一个course从数据库里被删除,你想把所有的相关classes也被删除,而且与这些classes相关的enrollments也被删除.为了实现这个目标,我们在数据库管理器中为这个关联设置一个级联删除,在数据库管理器中,选择该关联,在属性窗口的”INSERT 和UPDATE规范”下面选择级联删除.

当这些表导入到模型后,这个级联删除规则也会被导入,你可以

选择Course 和Class之间的一对多关系中然后在属性窗口里看到这个级联删除规则,如Figure 12-7 所示.

Figure 12-7. The cascade delete rule from the database was imported into the model, and it is shown in the properties for the association

如Figure 12-7所示的级联删除规则是在概念层的.在存储层也有一个类型的规则. 当一个对象被删除,EF规则及数据库里的级联删除规则,这二者是有必要使object context 和数据库保持同步.

Listing 12-5 代码演示了级联删除

Listing 12-5. Using the Underlying Cascade Delete Rules to Delete the Related Objects

class Program

{

static void Main(string[] args)

{

RunExample();

}

static void RunExample()

{

using (var context = new EFRecipesEntities())

{

var course1 = new Course { CourseName = "CS 301" };

var course2 = new Course { CourseName = "Math 455" };

var en1 = new Enrollment { Student = "James Folk" };

var en2 = new Enrollment { Student = "Scott Shores" };

var en3 = new Enrollment { Student = "Jill Glass" };

var en4 = new Enrollment { Student = "Robin Rosen" };

var class1 = new Class { Instructor = "Bill Meyers" };

var class2 = new Class { Instructor = "Norma Hall" };

class1.Course = course1;

class2.Course = course2;

class1.Enrollments.Add(en1);

class1.Enrollments.Add(en2);

class2.Enrollments.Add(en3);

class2.Enrollments.Add(en4);

context.Classes.Add(class1);

context.Classes.Add(class2);

context.SaveChanges();

context.Classes.Remove(class1);

context.SaveChanges();

}

using (var context = new EFRecipesEntities())

{

foreach (var course in context.Courses)

{

Console.WriteLine("Course: {0}", course.CourseName);

foreach (var c in course.Classes)

{

Console.WriteLine("\tClass: {0}, Instructor: {1}",

c.ClassId.ToString(), c.Instructor);

foreach (var en in c.Enrollments)

{

Console.WriteLine("\t\tStudent: {0}", en.Student);

}

}

}

}

Console.WriteLine("Press any key to close...");

Console.ReadLine();

}

}

上述Listing 12-5代码输出结果如下:

Course: CS 301

Course: Math 455

Class: 8, Instructor: Norma Hall

Student: Jill Glass

Student: Robin Rosen

原理

本小节里数据库与模型都定义了级联删除规则.在模型里,以确保object context与数据库同步.这个规则同时出现在概念层与存储层.

最佳实践

那么现在你可能会问:”为什么我们需要在数据库里与模型都定义这条规则?不能只在模型或是数据库里定义吗?”,级联删除存在于概念层来保持object context加载的对象是与数据库的级联删除后的结果是同步的.例如,如果我们已经在object context里为一个科目加载了相关的课程以及学生选课信息,然后我们把这个科目标志为删除,EF同样会把该科目的课程以及学生选课信息标志为删除.在把删除提交到数据库以前,在模型层,级联删除意味着只是把相关联的实体标志为删除,最终,EF才会把实体删除.那么既然EF会删除实体,那么为什么不能只在模型中定义级联删除呢?原因是: EF为了给实体标志为删除, DbContext 必须先加载这些实体,想象一下,如果我们的科目已被加载,但是相关的课程以学生选课信息未被加载,我们删除了科目,那么相关的课程及学生选课信息,由于未被DbContext 加载,所以EF无法将相关的实体标志为删除,也就无法向数据库发送删除相关记录的命令. 然而,如果我们在数据库里定义了级联删除,那么数据库自己就会很好的完成级联删除工作.

这里的最佳实践就是:在模型与数据库里同时定义级联删除规则.

如果你在一个模型里添加了一个级联删除规则,那么EF不会覆盖这条规则,即使你从数据库更新模型.

不幸的是,如果你没有在模型里添加级联删除规则,然后你从数据库更新实体,EF也不会向概念层添加在数据库里新添加的级联删除规则,你将不得不手动添加它.

附:创建示例用到的数据库的脚本文件

Entity Framework 6 Recipes 2nd Edition(12-5)译 -> 自动删除相关联实体的更多相关文章

  1. Entity Framework 6 Recipes 2nd Edition 译 -> 目录 -持续更新

    因为看了<Entity Framework 6 Recipes 2nd Edition>这本书前面8章的翻译,感谢china_fucan. 从第九章开始,我是边看边译的,没有通读,加之英语 ...

  2. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  3. Entity Framework 6 Recipes 2nd Edition(9-4)译->Web API 的客户端实现修改跟踪

    9-4. Web API 的客户端实现修改跟踪 问题 我们想通过客户端更新实体类,调用基于REST的Web API 服务实现把一个对象图的插入.删除和修改等数据库操作.此外, 我们想通过EF6的Cod ...

  4. Entity Framework 6 Recipes 2nd Edition(13-4)译 -> 有效地创建一个搜索查询

    问题 你想用LINQ写一个搜索查询,能被转换成更有效率的SQL.另外,你想用EF的CodeFirst方式实现. 解决方案 假设你有如下Figure 13-6所示的模型 Figure 13-6. A s ...

  5. Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include

    问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...

  6. Entity Framework 6 Recipes 2nd Edition(目录索引)

    Chapter01. Getting Started with Entity Framework / 实体框架入门 1-1. A Brief Tour of the Entity Framework ...

  7. Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体

    第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...

  8. Entity Framework 6 Recipes 2nd Edition(13-2)译 -> 用实体键获取一个单独的实体

    问题 不管你用DBFirst,ModelFirst或是CodeFirst的方式,你想用实体键获取一个单独的实体.在本例中,我们用CodeFirst的方式. 解决方案 假设你有一个模型表示一个Paint ...

  9. Entity Framework 6 Recipes 2nd Edition(13-3)译 -> 为一个只读的访问获取实体

    问题 你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现 解决方案 一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种 ...

随机推荐

  1. Cocos2d Android 环境搭建

    1.在开始之前,需要先准备好资源如下,如果安卓开发环境有了直接装第3.4. 1.JDK      点击下载 (1.6) 2.ADT(已经自带Android SDK)点击下载 3.NDK 点击下载 4. ...

  2. 比Mysqli操作数据库更简便的方式 。PDO

    下面来说一下PDO 先画一张图来了解一下 mysqli是针对mysql这个数据库扩展的一个类 PDO是为了能访问更多数据库 如果出现程序需要访问其他数据库的话就可以用PDO来做 PDO数据访问抽象层1 ...

  3. .NET Core的日志[3]:将日志写入Debug窗口

    定义在NuGet包"Microsoft.Extensions.Logging.Debug"中的DebugLogger会直接调用Debug的WriteLine方法来写入分发给它的日志 ...

  4. Asp.Net WebApi核心对象解析(上篇)

    生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...

  5. 【代码笔记】iOS-获得当前的月的天数

    一,代码. #import "ViewController.h" @interface ViewController () @end @implementation ViewCon ...

  6. 数据库 DML、DDL、DCL区别 .

    总体解释: DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的 ...

  7. git &github 快速入门

    本节内容 github介绍 安装 仓库创建& 提交代码 代码回滚 工作区和暂存区 撤销修改 删除操作 远程仓库 分支管理 多人协作 github使用 忽略特殊文件.gitignore 1.gi ...

  8. C++常考面试题汇总

    c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...

  9. 技术笔记:Indy IdSMTP支持腾讯QQ邮箱邮件发送

    1.腾讯QQ邮箱的授权码问题 因为腾讯邮箱折腾了个底朝天,其要搞什么授权码登录第三方客户端,否则会报这个错误: 'Error: 请使用授权码登录.详情请看: http://service.mail.q ...

  10. 为什么房间的 Wi-Fi 信号这么差

    最近把家里主卧整成了个小影院,由于之前房子装修时网线端口与电源插口布置太少,导致家庭网络架设变得麻烦起来,最后终于通过「无线中继」技术达到了全屋满格 Wi-Fi 的效果. 在 Wi-Fi 架设过程中, ...