设计器实体拆分

本演练演示如何使用实体框架设计器(EF 设计器)修改模型,将实体类型映射到两个表。 当表共享公共键时,可以将实体映射到多个表。 应用于将实体类型映射到两个表的概念很容易扩展到将实体类型映射到两个以上的表。

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

EF 设计器

先决条件

Visual Studio 2012 或 Visual Studio 2010、Ultimate、Premium、Professional 或 Web Express 版本。

创建数据库

随 Visual Studio 一起安装的数据库服务器因已安装的 Visual Studio 版本而异:

  • 如果使用 Visual Studio 2012,则将创建 LocalDB 数据库。
  • 如果使用 Visual Studio 2010,则将创建 SQL Express 数据库。

首先,我们将创建一个包含两个表的数据库,然后再将它们合并为一个实体。

  • 打开 Visual Studio
  • 视图 -> 服务器资源管理器
  • 右键单击 数据连接 -> 添加连接...
  • 如果尚未从服务器资源管理器连接到数据库,则需要选择 Microsoft SQL Server 作为数据源
  • 连接到已安装的 LocalDB 或 SQL Express 版本。
  • 输入 EntitySplitting 作为数据库名称
  • 选择“确定”,系统会询问是否要创建新数据库,选择“
  • 新数据库现在将显示在服务器资源管理器中
  • 如果使用 Visual Studio 2012
    • 右键单击服务器资源管理器中的数据库,然后选择 “新建查询”
    • 将以下 SQL 复制到新查询中,然后右键单击查询并选择“执行
  • 如果使用 Visual Studio 2010
    • 选择 数据 -> Transact SQL 编辑器 -> 新建查询连接...
    • 输入 .\SQLEXPRESS 作为服务器名称,然后单击“ 确定”
    • 从查询编辑器顶部的下拉列表中选择 EntitySplitting 数据库
    • 将以下 SQL 复制到新查询中,然后右键单击查询并选择“执行 SQL
CREATE TABLE [dbo].[Person] (
[PersonId] INT IDENTITY (1, 1) NOT NULL,
[FirstName] NVARCHAR (200) NULL,
[LastName] NVARCHAR (200) NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonId] ASC)
);

CREATE TABLE [dbo].[PersonInfo] (
[PersonId] INT NOT NULL,
[Email] NVARCHAR (200) NULL,
[Phone] NVARCHAR (50) NULL,
CONSTRAINT [PK_PersonInfo] PRIMARY KEY CLUSTERED ([PersonId] ASC),
CONSTRAINT [FK_Person_PersonInfo] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Person] ([PersonId]) ON DELETE CASCADE
);

创建项目

  • “文件” 菜单上,指向 “新建” ,然后单击 “项目”
  • 在左窗格中,单击 “Visual C#”,然后选择 控制台应用程序 模板。
  • 输入 MapEntityToTablesSample 作为项目的名称,然后单击“ 确定”。
  • 如果系统提示保存在第一节中创建的 SQL 查询,请单击 “否 ”。

基于数据库创建模型

  • 右键单击解决方案资源管理器中的项目名称,指向 “添加”,然后单击“ 新建项”。
  • 从左侧菜单中选择“数据”,然后在“模板”窗格中选择“ADO.NET 实体数据模型”
  • 输入 MapEntityToTablesModel.edmx 以获取文件名,然后单击“ 添加”。
  • 在“选择模型内容”对话框中,选择“ 从数据库生成”,然后单击“ 下一步”。
  • 从下拉列表中选择 EntitySplitting 连接,然后单击“ 下一步”。
  • 在“选择数据库对象”对话框中,选中 “表” 节点旁边的框。 这会将 EntitySplitting 数据库中的所有表添加到模型。
  • 单击“完成”。

将显示实体设计器,该设计器提供用于编辑模型的设计图面。

将实体映射到两个表

在此步骤中,我们将更新 Person 实体类型以合并 PersonPersonInfo 表中的数据。

  • 选择“PersonInfo”实体的电子邮件和电话属性,然后按 Ctrl+X 键。

  • 选择“人员”实体,然后按 Ctrl+V 键。

  • 在设计图面上,选择 PersonInfo 实体,然后按键盘上的 “删除 ”按钮。

  • 当系统询问是否要从模型中删除 PersonInfo 表时,单击“否”,我们将将其映射到 Person 实体。

    删除表

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

  • 选择人员实体类型,然后在映射详细信息窗口中单击<添加表或视图>
  • 从下拉列表中选择“PersonInfo”。 “映射详细信息”窗口使用默认列映射进行更新,这些映射适用于我们的方案。

Person 实体类型现在映射到 PersonPersonInfo 表。

映射 2

使用模型

  • 将以下代码粘贴到 Main 方法中。
    using (var context = new EntitySplittingEntities())
    {
        var person = new Person
        {
            FirstName = "John",
            LastName = "Doe",
            Email = "john@example.com",
            Phone = "555-555-5555"
        };

        context.People.Add(person);
        context.SaveChanges();

        foreach (var item in context.People)
        {
            Console.WriteLine(item.FirstName);
        }
    }
  • 编译并运行应用程序。

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

  • 执行 context.SaveChanges() 的结果是执行了以下两个 INSERT 语句。 他们从 Person 实体获取数据,并将其拆分为 PersonPersonInfo 表。

    插入 1

    插入 2

  • 枚举数据库中的人员后,执行了以下 SELECT 。 它合并了Person表和PersonInfo表中的数据。

    选择合并人员和PersonInfo数据