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. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  2. Android中手机录屏并转换GIF的两种方式

    之前在博文中为了更好的给大家演示APP的实现效果,本人了解学习了几种给手机录屏的方法,今天就给大家介绍两种我个人用的比较舒服的两种方法: (1)配置adb环境后,使用cmd命令将手机界面操作演示存为视 ...

  3. 探索ASP.NET MVC5系列之~~~2.视图篇(上)---包含XSS防御和异步分部视图的处理

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  4. app引导页(背景图片切换加各个页面动画效果)

    前言:不知不觉中又加班到了10点半,整个启动页面做了一天多的时间,一共有三个页面,每个页面都有动画效果,动画效果调试起来麻烦,既要跟ios统一,又要匹配各种不同的手机,然后产品经理还有可能在中途改需求 ...

  5. H5程序员如何利用cordova开发跨平台应用

    什么是Cordova? Cordova以前也叫PhoneGap,它提供了一组设备相关的API,通过这组API,移动应用能够以JavaScript访问原生的设备功能,如摄像头.麦克风等.Cordova还 ...

  6. ASP.NET Core 1.0 开发记录

    官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...

  7. CSS 3学习——box-sizing和背景

    box-sizing 在CSS 2中设置元素的width和height仅仅是设置了元素内容区的宽和高,元素实际的尺寸是margin + border + padding + 内容区. CSS 3(截止 ...

  8. 【教程】SQLite数据库修复

    SQLite 大家都知道,就不多说了. 有时候数据量大了,或者存储过程中出现异常,数据库就可能会出问题. 这是以前公司产品出现过的问题,导致软件都打不开了,我花了不少时间才解决的,趁现在有空贡献出来. ...

  9. BZOJ3198[SDOI2013]SPRING

    Description Input Output Sample Input 3 3 1 2 3 4 5 6 1 2 3 0 0 0 0 0 0 4 5 6 Sample Output 2 HINT 题 ...

  10. Mac OS X 上编写 ASP.NET vNext (二) IDE配置

    上一篇中介绍了如何在OS X上搭建.Net运行时.不过光有运行时还不够,还需要有一个好用的IDE,有了IDE的支持,OS X上的开发才称为可能. 和上篇类似,这里先列举出具体步骤,个人可以根据自己的情 ...