设计器表拆分

本演练演示如何使用 Entity Framework Designer(EF Designer)修改模型,将多个实体类型映射到单个表。

你可能会想使用表拆分的一个原因是,通过延迟加载来加载对象时,可以推迟某些属性的加载。 可以将可能包含大量数据的属性分隔到单独的实体中,并且仅在需要时加载它。

下图显示了使用 EF 设计器时使用的主窗口。

EF 设计器

先决条件

若要完成本演练,需要:

设置项目

本演练使用 Visual Studio 2012。

  • 打开 Visual Studio 2012。
  • “文件” 菜单上,指向 “新建” ,然后单击 “项目”
  • 在左窗格中,单击“Visual C#”,然后选择控制台应用程序模板。
  • 输入 TableSplittingSample 作为项目的名称,然后单击“ 确定”。

基于学校数据库创建模型

  • 右键单击解决方案资源管理器中的项目名称,指向 “添加”,然后单击“ 新建项”。
  • 从左侧菜单中选择 “数据” ,然后在“模板”窗格中选择 ADO.NET 实体数据模型
  • 为文件名输入 TableSplittingModel.edmx ,然后单击“ 添加”。
  • 在“选择模型内容”对话框中,选择“ 从数据库生成”,然后单击“ 下一步”。
  • 单击“新建连接”。 在“连接属性”对话框中,输入服务器名称(例如 (localdb)\mssqllocaldb),选择身份验证方法,键入 School 以获取数据库名称,然后单击“ 确定”。 “选择数据连接”对话框使用数据库连接设置进行更新。
  • 在“选择数据库对象”对话框中,展开 “表” 节点并检查 Person 表。 这会将指定的表添加到 学校 模型。
  • 单击“完成”。

将显示实体设计器,该设计器提供用于编辑模型的设计图面。 在“ 选择数据库对象 ”对话框中选择的所有对象都会添加到模型中。

将两个实体映射到单个表

在本部分中,你将Person实体拆分为两个实体,然后将其映射到单个表。

注释

Person 实体不包含可能包含大量数据的任何属性;它只是用作示例。

  • 右键单击设计图面的空白区域,指向“ 添加新”,然后单击“ 实体”。 此时会显示“ 新建实体 ”对话框。
  • HireInfo类型的实体名称PersonID类型的Key 属性名称键入。
  • 单击 “确定”
  • 新实体类型在设计图面上创建并显示。
  • 选择 Person 实体类型的 HireDate 属性,然后按 Ctrl+X 键。
  • 选择 HireInfo 实体,然后按 Ctrl+V 键。
  • 创建 PersonHireInfo 之间的关联。 为此,请右键单击设计图面的空白区域,指向“ 添加新”,然后单击“ 关联”。
  • 此时会显示“ 添加关联 ”对话框。 默认情况下会提供 PersonHireInfo 名称。
  • 在关系的两端指定乘数 1(一)。
  • 按下“确定”

下一步需要 “映射详细信息” 窗口。 如果看不到此窗口,请右键单击设计图面,然后选择“ 映射详细信息”。

  • 选择 HireInfo 实体类型,然后在 映射详细信息 窗口中单击 <添加表或视图>

  • <“添加表或视图”>字段下拉列表中选择人员。 该列表包含所选实体可映射到的表或视图。 默认情况下,应映射相应的属性。

    映射属性

  • 在设计界面上选择 PersonHireInfo 关联。

  • 右键单击设计图面上的关联并选择“ 属性”。

  • “属性” 窗口中,选择 “引用约束 ”属性,然后单击省略号按钮。

  • “主体”下拉列表中选择“人员”。

  • 按下“确定”

 

使用模型

  • 将以下代码粘贴到 Main 方法中。
    using (var context = new SchoolEntities())
    {
        Person person = new Person()
        {
            FirstName = "Kimberly",
            LastName = "Morgan",
            Discriminator = "Instructor",
        };

        person.HireInfo = new HireInfo()
        {
            HireDate = DateTime.Now
        };

        // Add the new person to the context.
        context.People.Add(person);

        // Insert a row into the Person table.  
        context.SaveChanges();

        // Execute a query against the Person table.
        // The query returns columns that map to the Person entity.
        var existingPerson = context.People.FirstOrDefault();

        // Execute a query against the Person table.
        // The query returns columns that map to the Instructor entity.
        var hireInfo = existingPerson.HireInfo;

        Console.WriteLine("{0} was hired on {1}",
            existingPerson.LastName, hireInfo.HireDate);
    }
  • 编译并运行应用程序。

由于运行此应用程序,以下 T-SQL 语句针对 School 数据库执行。 

  • 执行 `context.SaveChanges()` 后,以下 INSERT 被执行,并合并了 PersonHireInfo 实体中的数据。

    插入合并人员和雇佣信息数据

  • 执行 context.People.FirstOrDefault() 后,执行了下面的 SELECT,仅选择映射到 Person 的列。

    选择 1

  • 由于访问 existingPerson.Instructor 的导航属性,执行了以下 SELECT,仅选择映射到 HireInfo 的列

    选择 2