演练5-7:Contoso大学校园管理系统(实现继承)
***操作视频下载:1 ***
在上一次教程中,你已经能够处理并发异常。这个教程将会展示如何在数据模型中实现继承。
在面向对象的程序设计中,你可以通过继承来清除冗余的代码。在这个教程中,你将要通过修改教师 Instructor 和学生 Student 类,以便使他们从包含类似 LastName 属性的 Person 类中派生。对于 Web 页面不需要任何改动,你需要修改一点代码,这些修改将会被自动反射到数据库中。
一、单表继承 (Table-per-Hierarchy) vs 类型表 (Table-per-Type) 继承
在面向对象的程序设计中,你可以通过对相关的类使用继承来使得工作更加简单。例如,教师 Instructor 和学生 Student 类在学校 School 数据模型中共享多个属性,带来了冗余的代码。

假设你希望清除在教师 Instructor 和学生 Student 之间所共享的属性带来的冗余代码。可以创建一个 Person 基类,其中仅仅包含他们共享的属性,然后,使得教师 Instructor 和学生 Student 类从 Person 基类派生,如下图所示。

在数据库中这种继承结构可以有多种表现形式,可以创建一个名为 Person 的表,在这个独立的表中包含教师和学生所有的信息。既包括他们独自拥有的属性 ( 例如教师的 HireDate ,以及学生的 EnrollmentDate ),也包括它们共有的属性 ( 例如 LastName, FirstName )。通常你还需要一个用于识别当前类型的列 discriminator 来标识当前行的类型。( 在这里,标识列的内容为 Instructor 来表示教师,Student 来表示学生 )

使用单个数据库表来生成实体继承结构的模式称为单表继承模式 TPH (table-per-hierarchy )。
另外一种方式是使得数据库看起来类似继承结构。例如,在 Person 表中仅仅包含他们共有的名字属性,而将不同的时间分别保存到独立的 Instructor 和 Student 表中。 
这种每种实体类对应一张数据库表的模式称为类型表 TPT 继承 (table per type )。 在 EF 中,TPH 继承比 TPT 继承有更好的性能,因为 TPT 继承需要复杂的连接查询。这个教程演示如何实现 TPH 继承。你需要完成如下的步骤:
- 创建 Person 类,将 Instructor 和 Student 类从 Person 类中派生
- 在数据库上下文类中增加模型到数据库的映射代码
- 将项目中的 InstructorID 和 StudentID 修改为使用 PersonID.
二、创建 Person 类
在 Model 文件夹中,创建 Person.cs ,使用下面的代码替换原有的代码。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models
{
public abstract class Person
{
[Key]
public int PersonID { get; set; } [Required(ErrorMessage = "Last name is required.")]
[Display(Name="Last Name")]
[MaxLength(50)]
public string LastName { get; set; } [Required(ErrorMessage = "First name is required.")]
[Column("FirstName")]
[Display(Name = "First Name")]
[MaxLength(50)]
public string FirstMidName { get; set; } public string FullName
{
get
{
return LastName + ", " + FirstMidName;
}
}
}
}

在 Instructor.cs 文件中,将 Instructor 从 Person 派生出来,删除 key 和 name 字段。代码如下所示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models
{
public class Instructor : Person
{
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Required(ErrorMessage = "Hire date is required.")]
[Display(Name = "Hire Date")]
public DateTime? HireDate { get; set; } public virtual ICollection<Course> Courses { get; set; } public virtual OfficeAssignment OfficeAssignment { get; set; }
}
}

对 Student.cs 文件进行类似的修改,修改后的 Student 类如下所示。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models
{
public class Student : Person
{
[Required(ErrorMessage = "Enrollment date is required.")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Display(Name = "Enrollment Date")]
public DateTime? EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

三、在模型中增加 Person 实体类型
在 SchoolContext.cs 文件中,对 Person 实体类型增加一个 DbSet 类型的属性。
public DbSet<Person> People { get; set; }
这就是在 EF 中配置 TPH 继承所有需要完成的工作。如你所见,当数据库重建的时候,EF 会自动创建 Person 表。
四、修改 InstructorID 和 StudentID 为 PersonID
进行一次全局的替换 ( 项目中所有的文件 ),将 InstructorID 修改为 PersonID,StudentID 修改为 PersonID。注意区分大小写。( 这里演示了使用类名加上 ID 作为主键的一个缺点。如果你没有使用类名加上 ID 作为主键,这里就不需要重新命名 )
进行模型迁移,add-migration inheritance, update-database,遇到问题的话,直接删了数据库,且更改webconfig,然后再来。
七、测试
运行程序,在各个页面上检查一下,所有的工作如以前一样。 在解决方案管理器上,双击 School.sdf 数据库,在服务器资源管理器中打开,展开 School.sdf,然后选择 Tables,你会看到 Student 和 Instructor 表已经被 Person 表替换掉了。展开 Person 表,你会看到其中拥有原来 Student 和 Instructor 中所有的列,加上 discriminator 列。

下图展示了新的 School 数据库的结构。

对于 Person ,Student 和 Instructor 类,通过 TPH 实现了继承。对于更多的关于其他继承结构,可以查看 Morteza Manavi 的博客 Inheritance Mapping Strategies。在下一次的教程中,将会学习实现仓储和单元模式的一些途径。
演练5-7:Contoso大学校园管理系统(实现继承)的更多相关文章
- 演练5-3:Contoso大学校园管理系统3
在前面的教程中,我们使用了一个简单的数据模型,包括三个数据实体.在这个教程汇中,我们将添加更多的实体和关系,按照特定的格式和验证规则等自定义数据模型. Contoso大学校园管理系统的数据模型如下. ...
- 演练5-5:Contoso大学校园管理系统5
Contoso University示例网站演示如何使用Entity Framework 5创建ASP.NET MVC 4应用程序. Entity Framework有三种处理数据的方式: Data ...
- 演练5-6:Contoso大学校园管理系统6
在上一次的教程中,我们处理了关联数据问题.这个教程演示如何处理并发问题.你将使用Department实体创建一个页面,这个页面在支持编辑和删除的同时,还可以处理并发错误.下面的截图演示了Index页面 ...
- 演练5-4:Contoso大学校园管理系统4
在之前的教程中,我们已经完成了学校的数据模型.现在我们将读取和显示相关数据,请理解EF加载导航属性的方式. 一.Lazy.Eager.Explicit数据加载 使用EF为实体中的导航属性加载相关数据, ...
- 演练5-8:Contoso大学校园管理系统(实现存储池和工作单元模式)
在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码.在这个教程中,你将要看到使用存储池和工作单元模式进行增.删.改.查的一些方法.像前面的教程一样, ...
- 演练5-1:Contoso大学校园管理1
**演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...
- 演练5-2:Contoso大学校园管理2
一.添加列标题排序功能 我们将增加Student/Index页面的功能,为列标题添加超链接,用户可以点击列标题对那一列进行排序. 1.修改Index方法 public ActionResult Ind ...
- Contoso 大学 - 使用 EF Code First 创建 MVC 应用,实例演练
Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Contoso 大学是虚构的.应用包括了类似学生注册.课程创建以及教师分配等功能. 这个系 ...
- Contoso 大学 - 7 – 处理并发
原文 Contoso 大学 - 7 – 处理并发 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's W ...
随机推荐
- malloc、calloc、realloc三者的差别
1.malloc 作用:分配内存块 原型:void *malloc(size_t size);size表示要分配的字节数 返回值:返回一个指向所分配空间的void指针,假设没有足够的内存可用,则返回N ...
- openstack第1天
入门openstack题外篇 老实说,我在写这篇文章的时候,对云的了解还是比较模糊的,也许是刚接触,不管怎样 总得写点什么,写完之后也许数月之后,感觉写的不是那么好,到时候在做修该吧! 今天我们就提一 ...
- STL之list(双向链表)
一,概述 List将元素按顺序储存在链表中. 与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢. list 不仅是一个双向链表,而且是一个环状双向链表 二,使用 #incl ...
- [LeetCode]题解(python):049-Group Anagrams
题目来源: https://leetcode.com/problems/anagrams/ 题意分析: 给定一个字符串数组,将用相同字母(包括个数)组成的字符串放到一起.比如["eat&qu ...
- 浙江大学PAT上机题解析之2-11. 两个有序链表序列的合并
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的并集新非降序链表S3. 输入格式说明: 输入分2行,分别在每行给出由若干个正整数构成的非降序序列,用-1表示序列的结尾(-1不属于这个序列) ...
- mmc一维下料测试
另一组数据, 长度 = 6000; 切割长度 = {1664, 1599, 1552, 1409, 1352, 802, 660}; 需求数量 = {32, 96, 160, 16, 384, 112 ...
- Android:源码环境编译自定义的APP到ROM(System Image)中
有时候我们需要在源码环境中增加自己的应用或模块,随ROM一起发布. 下面讲述相关步骤: 1. 首先可以在SDK环境下进行编码设计(如果你的APP不涉及到emulator无法模拟的硬件的话) 也可以参考 ...
- IOS 时间格式 时间转换 大总结
//实例化一个NSDateFormatter对象 NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init]; //设定时间格式,这里 ...
- UIApplication相关
1,显示应用图标右上角的红色提示 application.applicationIconBadgeNumber = 10; 2.修改状态栏的类型 在当前控制器下设置 - (UIStatusBarSty ...
- 自定义ActionBar背景(分别针对3.0以下和3.0以上的版本)
官方原文:http://developer.android.com/training/basics/actionbar/styling.html 针对3.0以上的版本: <?xml versio ...