Designer 表拆分

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

使用表拆分的原因之一可能是使用延迟加载加载对象时会延迟加载某些属性。 可以将可能包含大量数据的属性分离到一个独立的实体中,并且仅在需要时加载。

下图显示了使用 EF Designer 时使用的主窗口。

EF Designer

先决条件

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

设置项目

本演练使用 Visual Studio 2012。

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

创建基于 School 数据库的模型

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

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

将两个实体映射到单个表

在本部分中,你会将“人员”实体拆分为两个实体,然后将其映射到单个表

注意

“人员”实体不包含任何可能包含大量数据的属性;它仅用作示例

  • 右键单击设计图面的空白区域,指向“添加新项”,然后单击“实体”。 此时将出现“新建实体”对话框
  • 输入 HireInfo 作为实体名称,输入 PersonID 作为关键属性名称
  • 单击“确定”。
  • 新的实体类型创建完毕,并且显示在设计图面上。
  • 选择“人员”实体类型的 HireDate 属性,然后按 Ctrl+X 键
  • 选择 HireInfo 实体,然后按 Ctrl+V 键
  • 创建“人员”和 HireInfo 之间的关联。 为此,右键单击设计图面的空白区域,指向“添加新项”,然后单击“关联”
  • 此时将出现“添加关联”对话框。 默认给出 PersonHireInfo 名称
  • 在关系的两端指定多重性 1(一)
  • 按“确定”。

下一步骤要求使用“映射详细信息”窗口。 如果没有出现此窗口,请右键单击设计图面,然后选择“映射详细信息”

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

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

    Mapping Properties

  • 选择设计图面上的 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);
    }
  • 编译并运行该应用程序。

运行此应用程序后会对 School 数据库执行以下 T-SQL 语句。 

  • 执行 context.SaveChanges() 后会执行以下 INSERT 语句,该语句会合并“人员”和 HireInfo 实体中的数据

    Insert Combining Person and HireInfo Data

  • 执行 context.People.FirstOrDefault() 后会执行以下 SELECT 语句,该语句会选择映射到“人员”的列

    Select 1

  • 访问导航属性 existingPerson.Instructor 后会执行以下 SELECT 语句,该语句会选择映射到 HireInfo 的列

    Select 2