Designer TPT 继承

此分步式演练介绍如何使用 Entity Framework Designer (EF Designer) 在模型中实现每个类型一张表 (TPT) 继承。 每种类型一个表继承使用数据库中单独的表为继承层次结构中的每种类型维护非继承属性和键属性的数据。

在本演练中,我们会将 Course(基类型)、OnlineCourse(源自 Course)和 OnsiteCourse(源自 Course)实体映射到同名的表。 我们将从数据库创建模型,然后更改该模型以实现 TPT 继承。

也可以从 Model First 开始,然后从模型生成数据库。 EF Designer 默认使用 TPT 策略,因此模型中的所有继承都将映射到独立的表。

其他继承选项

每个层次结构一张表 (TPH) 是另一种类型的继承,其中使用一个数据库表来维护继承层次结构中所有实体类型的数据。  有关如何使用 Entity Designer 映射每个层次结构一张表继承的信息,请参阅 EF Designer TPH 继承。 

请注意,实体框架运行时支持按具体表类型继承 (TPC) 和混合继承模型,但 EF 设计器不支持。 如果要使用 TPC 或混合继承,你有两个选择:使用 Code First,或手动编辑 EDMX 文件。 如果选择使用 EDMX 文件,映射详细信息窗口将进入“安全模式”,你将无法使用设计器更改映射。

先决条件

若要完成此演练,您需要:

设置项目

  • 打开 Visual Studio 2012。
  • 选择“文件”->“新建”->“项目”
  • 在左窗格中,单击“Visual C#”,然后选择“控制台”模板
  • 输入 TPTDBFirstSample 作为名称
  • 选择“确定”

创建模型

  • 在“解决方案资源管理器”中右键单击该项目,然后选择“添加”>“新建项”
  • 从左侧菜单中选择“数据”,然后在“模板”窗格中选择“ADO.NET 实体数据模型”
  • 输入“TPTModel.edmx”作为文件名,然后单击“添加”
  • 在“选择模型内容”对话框中,选择 **从数据库生成**,然后单击“下一步”
  • 单击“新建连接”。 在“连接属性”对话框中,输入服务器名称(例如 (localdb)\mssqllocaldb),选择身份验证方法,键入 School 作为数据库名称,然后单击“确定”。 “选择数据连接”对话框将根据你的数据库连接设置进行更新。
  • 在“选择数据库对象”对话框中的“表”节点下,选择“院系”、“Course、OnlineCourse 和 OnsiteCourse”表
  • 单击“完成” 。

将显示 Entity Designer,它提供用于编辑模型的设计图面。 在“选择数据库对象”对话框中选择的所有对象都已经添加到模型中。

实现每个类型一张表继承

  • 在设计图面上,右键单击 OnlineCourse 实体类型并选择“属性”
  • 在“属性”窗口中,将“基类型”属性设置为 Course
  • 右键单击 OnsiteCourse 实体类型并选择“属性”
  • 在“属性”窗口中,将“基类型”属性设置为 Course
  • 右键单击 OnlineCourse 与 Course 实体类型之间的关联(线)。 选择“从模型删除”
  • 右键单击 OnsiteCourse 与 Course 实体类型之间的关联。 选择“从模型删除”

现在,我们将从 OnlineCourse 和 OnsiteCourse 中删除 CourseID 属性,因为这些类从 Course 基类型继承 CourseID

  • 右键单击 OnlineCourse 实体类型的 CourseID 属性,然后选择“从模型中删除”
  • 右键单击 OnsiteCourse 实体类型的 CourseID 属性,然后选择“从模型中删除”
  • 至此已实现每种类型一个表继承。

Table Per Type

使用模型

打开 Program.cs 文件,其中定义了 Main 方法。 将以下代码粘贴到 Main 函数中。 该代码执行三个查询。 第一个查询返回与指定院系相关的所有 Course。 第二个查询使用 OfType 方法返回与指定院系相关的 OnlineCourses。 第三个查询返回 OnsiteCourses

    using (var context = new SchoolEntities())
    {
        foreach (var department in context.Departments)
        {
            Console.WriteLine("The {0} department has the following courses:",
                               department.Name);

            Console.WriteLine("   All courses");
            foreach (var course in department.Courses )
            {
                Console.WriteLine("     {0}", course.Title);
            }

            foreach (var course in department.Courses.
                OfType<OnlineCourse>())
            {
                Console.WriteLine("   Online - {0}", course.Title);
            }

            foreach (var course in department.Courses.
                OfType<OnsiteCourse>())
            {
                Console.WriteLine("   Onsite - {0}", course.Title);
            }
        }
    }