演练:将一个实体映射到多个表(实体数据模型工具)
本主题介绍如何通过修改概念模型将一个实体类型映射到两个表。 如果多个表共享同一个公共键,则可以将一个实体映射到这些表。 适用于将一个实体类型映射到两个表的概念,可以轻松扩展为将一个实体类型映射到两个以上的表。
在本演练中,您将通过修改 CourseManager 应用程序中使用的概念模型将一个实体类型映射到两个表(有关更多信息,请参见本主题后面的“先决条件”一节)。 您将创建一个新的实体类型(派生自 Person 实体类型的 Instructor),并将之映射到 Person 和 OfficeAssignment 表。 下面的步骤概述了该过程(有关更多详细信息,请参见本文档稍后的过程):
创建新的实体类型 Instructor。
将 Instructor 的基类型设置为 Person。
注意: 为了将一个实体类型映射到多个表,不必创建继承层次结构。在本例中使用继承层次结构是为了更加贴近现实(在一所学校中,只有一名教师将会获得办公室分配)。不必创建 Instructor 实体类型,便可以将 Person 实体类型同时映射到 Person 和 OfficeAssignment 表。 将 HireDate 属性从 Person 移到 Instructor。
将 Location 和 Timestamp 属性从 OfficeAssignment 移到 Instructor。
按照 HireDate Is Not Null 条件将 Instructor 实体映射到 Person 表。 将 HireDate 列映射到 HireDate 属性。
无条件将 Instructor 实体映射到 OfficeAssignment 表。 将 InstructorID 列映射到 PersonID 属性,将 Location 列映射到 Location 属性。
删除 OfficeAssignment 实体类型。
必备条件
要完成本演练,必须生成 CourseManager 应用程序。 有关更多信息,请参见实体框架快速入门。 您将通过添加新的实体类型并将该类型映射到两个表来修改在 CourseManager 应用程序中使用的概念模型。 然后,扩展应用程序的功能,以显示教师的办公室分配情况。
注意: |
---|
因为本文档中的许多演练主题都使用该 CourseManager 应用程序作为起点,所以建议在本演练中使用 CourseManager 应用程序的副本,而不要编辑原始 CourseManager 代码。 |
此演练假定读者对于 Visual Studio、.NET Framework 以及使用 Visual C# 或 Visual Basic 编程具有基本的了解。
将一个实体映射到两个表
在此过程中,您将通过创建一个新的实体类型 (Instructor) 并将该类型映射到两个表(Person 和 OfficeAssignment)来修改 School.edmx 文件的 CSDL 和映射内容。
将一个实体映射到两个表
在 Visual Studio 中打开 CourseManager 解决方案。
在解决方案资源管理器中,双击 School.edmx 文件。
School.edmx 文件在实体数据模型设计器(实体设计器)中打开。
右键单击实体设计器设计图面的空白区域,指向**“添加”,然后单击“实体”**。
此时将显示**“新建实体”**对话框。
对于**“实体名称”请键入 Instructor,然后从“基类型”**下拉列表中选择 Person。
单击**“确定”**。
新的实体类型创建完毕,并且显示在设计图面上。
右键单击 Person 实体类型的 HireDate 属性(在**“标量属性”下面),然后选择“剪切”**。
右键单击 Instructor 实体类型的**“标量属性”,然后选择“粘帖”**。
右键单击 HireDate 属性,然后选择**“属性”**。
此时将显示**“属性”**窗口。
在**“属性”窗口中,将“可以为 Null”**属性设置为 false。
右键单击 OfficeAssignment 实体类型的 Location 属性,然后选择**“剪切”**。
右键单击 Instructor 实体类型的**“标量属性”,然后选择“粘帖”**。
右键单击 Location 属性,然后选择**“属性”**。
在**“属性”窗口中,将“可以为 Null”**属性设置为 false。
对于 OfficeAssignment 类型的 Timestamp 属性重复步骤 10 到 13。
注意: 下一步骤要求使用“映射详细信息”窗口。如果没有出现此窗口,请右键单击设计图面,然后选择“映射详细信息”。 选择 Instructor 实体类型,然后单击**“映射详细信息”窗口中的“<添加表或视图>”**。
**“<添加表或视图>”**字段变成下拉列表,其中包含选定实体可映射到的表或视图。
从下拉列表中选择 Person。
**“映射详细信息”**窗口将会根据默认列映射以及一个关于添加条件的选项而进行更新。
单击**“<添加条件>”**。
**“<添加条件>”**字段变成一个包含列的下拉列表(可为其中各列设置条件)。
从下拉列表中选择 HireDate。
在**“映射详细信息”窗口的“运算符”列中,从下拉列表中选择“Is”**。
在**“映射详细信息”窗口的“属性/值”列中,选择“Not Null”**。
单击**“<添加表或视图>”**,然后从下拉列表中选择 OfficeAssignment。
**“映射详细信息”**窗口将会根据默认的列映射进行更新。
单击对应于 InstructorID 列的**“属性/值”**字段,然后从下拉列表中选择 PersonID。
右键单击 OfficeAssignment 实体类型,然后选择**“删除”**。
Instructor 实体类型现在已经映射到 Person 和 OfficeAssignment 表。
构造用户界面
接下来,将向 CourseViewer 窗体添加一个用于加载和显示 CourseAssignmentForm 窗体的按钮。 然后,将用于显示 Instructor 办公室位置的 DataGridView 控件添加到窗体中。 最后,向 CourseAssignmentForm 窗体添加一个将更新保存到数据库中的按钮。
构造用户界面
在**“解决方案资源管理器”中右击 CourseManager 项目,指向“添加”,然后选择“新建项”**。
此时将显示**“添加新项”**对话框。
选择**“Windows 窗体”,将窗体的名称设置为 OfficeAssignment.vb 或 OfficeAssignment.cs,然后单击“添加”**。
新窗体即被添加到项目中,并在窗体设计器中打开。 窗体的名称设置为 OfficeAssignment,文本设置为 OfficeAssignment。
将 DataGridView 控件拖入窗体,然后将其名称设置为 officeGridView。
单击 DataGridView 的智能标记,然后清除**“启用添加”和“启用删除”**选项。
将 Button 控件拖入窗体,然后将其名称属性设置为 saveChanges,并将其文本属性设置为 Update。
在**“解决方案资源管理器”**中,双击 CourseViewer.cs 或 CourseViewer.vb。
出现 CourseViewer 窗体的设计视图。
从工具箱将 Button 控件拖入 CourseViewer 窗体。
在**“属性”**窗口中,将按钮的名称设置为 viewOffices,然后将按钮的文本设置为 View Offices。
双击 viewOffices Button。
CourseViewer 的代码隐藏文件打开。
将下面的代码添加到 viewOffices_click 事件处理程序中:
Dim officeForm As New OfficeAssignment() officeForm.Visible = True
OfficeAssignment officeForm = new OfficeAssignment(); officeForm.Visible = true;
现在,就完成了此窗体的用户界面。
查询概念模型
此应用程序通过将 DataGridView 控件绑定到查询来显示数据。 允许编辑显示在 DataGridView 控件中的信息,并且可以将更改保存到数据库中。 有关将对象绑定到控件的更多信息,请参见Binding Objects to Controls (Entity Framework)。
查询概念模型
在窗体设计器中打开 OfficeAssignment 窗体后,双击窗体主体。
此时将打开 OfficeAssignment 窗体的代码隐藏文件。
添加以下 using (C#) 或 Imports (Visual Basic) 语句,以引用基于 School 数据库和实体命名空间创建的模型。
Imports System.Data.Objects Imports System.Data.Objects.DataClasses
using System.Data.Objects; using System.Data.Objects.DataClasses;
将表示数据上下文的属性添加到 OfficeAssignment 类中:
' Create an ObjectContext instance based on SchoolEntity. Private schoolContext As SchoolEntities
// Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext;
在 OfficeAssignment_Load 事件处理程序中,添加代码以初始化对象上下文并将 DataGridView 控件绑定到返回 Instructor 信息的查询。
' Initialize the ObjectContext. schoolContext = New SchoolEntities() ' Get Persons of type Instructor. Dim instructorQuery As ObjectQuery(Of Instructor) = _ schoolContext.People.OfType(Of Instructor)() ' Bind the query results to the GridView control. ' Display only location and name. officeGridView.DataSource = instructorQuery _ .Execute(MergeOption.OverwriteChanges) officeGridView.Columns("HireDate").Visible = False officeGridView.Columns("PersonID").Visible = False officeGridView.Columns("Timestamp").Visible = False officeGridView.Columns("EnrollmentDate").Visible = False officeGridView.Columns("StudentGrades").Visible = False officeGridView.Columns("Courses").Visible = False
schoolContext = new SchoolEntities(); // Get Persons of type Instructor. ObjectQuery<Instructor> instructorQuery = schoolContext .People.OfType<Instructor>(); // Bind the query results to the GridView control. // Display only location and name. officeGridView.DataSource = instructorQuery .Execute(MergeOption.OverwriteChanges); officeGridView.Columns["HireDate"].Visible = false; officeGridView.Columns["Timestamp"].Visible = false; officeGridView.Columns["PersonID"].Visible = false; officeGridView.Columns["EnrollmentDate"].Visible = false; officeGridView.Columns["StudentGrades"].Visible = false; officeGridView.Columns["Courses"].Visible = false;
返回 OfficeAssignment 窗体的设计视图,然后双击 saveChanges Button 控件。
saveChanges_Click 事件处理程序在代码隐藏文件中创建。
在事件处理程序中添加代码,从而将曾在 DataGridView 控件中所做的所有更改保存到数据库中。
' Save object changes to the database, ' display a message, and refresh the form. schoolContext.SaveChanges() MessageBox.Show("Change(s) saved to the database.") Me.Refresh()
// Save object changes to the database, // display a message, and refresh the form. schoolContext.SaveChanges(); MessageBox.Show("Change(s) saved to the database."); this.Refresh();
现在,就完成了应用程序。 按 Ctrl+F5 运行应用程序。 单击 View Offices 按钮以加载 OfficeAssignments 窗体。 出现教师姓名和办公室位置。 允许编辑显示出来的信息,并且可以通过单击 Update 按钮而将更改保存到数据库中。
代码清单
本节列出了 OfficeAssignmentForm 窗体的代码隐藏文件的最终版本。
Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class OfficeAssignment
' Create an ObjectContext instance based on SchoolEntity.
Private schoolContext As SchoolEntities
Private Sub OfficeAssignment_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
' Initialize the ObjectContext.
schoolContext = New SchoolEntities()
' Get Persons of type Instructor.
Dim instructorQuery As ObjectQuery(Of Instructor) = _
schoolContext.People.OfType(Of Instructor)()
' Bind the query results to the GridView control.
' Display only location and name.
officeGridView.DataSource = instructorQuery _
.Execute(MergeOption.OverwriteChanges)
officeGridView.Columns("HireDate").Visible = False
officeGridView.Columns("PersonID").Visible = False
officeGridView.Columns("Timestamp").Visible = False
officeGridView.Columns("EnrollmentDate").Visible = False
officeGridView.Columns("StudentGrades").Visible = False
officeGridView.Columns("Courses").Visible = False
End Sub
Private Sub saveChanges_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles saveChanges.Click
' Save object changes to the database,
' display a message, and refresh the form.
schoolContext.SaveChanges()
MessageBox.Show("Change(s) saved to the database.")
Me.Refresh()
End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace CourseManager
{
public partial class OfficeAssignment : Form
{
// Create an ObjectContext instance based on SchoolEntity.
private SchoolEntities schoolContext;
public OfficeAssignment()
{
InitializeComponent();
}
private void OfficeAssignment_Load(object sender, EventArgs e)
{
schoolContext = new SchoolEntities();
// Get Persons of type Instructor.
ObjectQuery<Instructor> instructorQuery = schoolContext
.People.OfType<Instructor>();
// Bind the query results to the GridView control.
// Display only location and name.
officeGridView.DataSource = instructorQuery
.Execute(MergeOption.OverwriteChanges);
officeGridView.Columns["HireDate"].Visible = false;
officeGridView.Columns["Timestamp"].Visible = false;
officeGridView.Columns["PersonID"].Visible = false;
officeGridView.Columns["EnrollmentDate"].Visible = false;
officeGridView.Columns["StudentGrades"].Visible = false;
officeGridView.Columns["Courses"].Visible = false;
}
private void saveChanges_Click(object sender, EventArgs e)
{
// Save object changes to the database,
// display a message, and refresh the form.
schoolContext.SaveChanges();
MessageBox.Show("Change(s) saved to the database.");
this.Refresh();
}
}
}
后续步骤
您已成功将一个实体映射到多个表。 有关如何创建一个实体映射到多个表的模型的更多信息,请参见How to: Define a Model with a Single Entity Mapped to Two Tables。 有关如何生成使用实体框架的应用程序的更多信息,请参见ADO.NET Entity Framework。