Пошаговое руководство по сопоставлению наследования — одна таблица на тип (средства модели EDM)
В этом подразделе показано, как реализовать наследование типа «одна таблица на тип» путем изменения концептуальной модели. В наследовании типа «одна таблица на тип» используется отдельная таблица в базе данных для сопровождения данных, относящихся к ненаследуемым свойствам и ключевым свойствам для каждого типа в иерархии наследования.
В этом пошаговом руководстве будет реализовано наследование типа «одна таблица на тип» путем изменения концептуальной модели, используемой в приложении CourseManager (дополнительные сведения см. в подразделе «Предварительные условия» далее в этом разделе).
В приложении CourseManager типы сущностей Course, OnlineCourse и OnsiteCourse сопоставляются с одноименными таблицами. Типы сущностей OnlineCourse и OnsiteCourse содержат сведения, уникальные для двух типов курсов, и имеют общий ключ, поэтому их можно изменить, чтобы обеспечить наследование от типа сущности Course. На следующих шагах обобщается способ реализации наследования типа «одна таблица на тип» в подобном случае (далее в этом документе приведены процедуры, которые содержат дополнительные сведения).
Удалите ассоциацию между типом сущности OnlineCourse и типом сущности Course. Удалите ассоциацию между типом сущности OnsiteCourse и типом сущности Course. Эти ассоциации можно заменить реализацией иерархии наследования.
Удалите ключевое свойство CourseID из типов сущностей OnlineCourse и OnsiteCourse. Это свойство также наследуется от типа сущности Course.
Установите тип сущности Course как базовый тип для типов сущностей OnlineCourse и OnsiteCourse.
Преобразуйте тип сущности Course в абстрактный тип.
Сопоставьте унаследованные свойства CourseID типов сущностей OnlineCourse и OnsiteCourse с соответствующими столбцами.
Предварительные требования
Чтобы завершить работу с этим пошаговым руководством, необходимо вначале построить приложение CourseManager. Дополнительные сведения и инструкции см. в разделе Краткое руководство по платформе Entity Framework. Будет реализовано наследование типа «одна таблица на тип» путем изменения концептуальной модели, используемой в приложении CourseManager. Затем будут расширены функциональные возможности приложения, чтобы можно было отдельно отображать оперативные и очные курсы для выбранного отдела.
Примечание |
---|
Приложение CourseManager используется в качестве отправной точки во многих разделах пошагового руководства в данной документации, поэтому рекомендуется использовать для данного пошагового руководства копию приложения CourseManager, а не вносить изменения в первоначальный код CourseManager. |
В пошаговом руководстве предполагается, что читатель владеет основами среды Visual Studio, платформы .NET Framework и программирования на языке Visual C# или Visual Basic.
Реализация наследования типа «одна таблица на тип»
В этой процедуре будет изменена модель SchoolModel путем реализации наследования типа «одна таблица на тип». Видеопрезентацию следующей процедуры см. в разделе Как.
Реализация наследования типа «одна таблица на тип»
Откройте решение CourseManager в среде Visual Studio.
В обозревателе решений дважды щелкните файл School.edmx.
Файл School.edmx открывается в конструкторе моделей EDM ADO.NET (конструктор сущностей).
Щелкните правой кнопкой мыши тип сущности OnlineCourse и выберите пункт Свойства.
В окне Свойства установите свойство Базовый тип в значение Course.
Повторите шаги 3 и 4 для типа сущности OnsiteCourse.
Щелкните правой кнопкой мыши ассоциацию (линию) между типами сущностей OnlineCourse и Course. Выберите команду Удалить.
Щелкните правой кнопкой мыши ассоциацию между типами сущностей OnsiteCourse и Course. Выберите команду Удалить.
Щелкните правой кнопкой мыши свойство CourseID типа сущности OnlineCourse, а затем выберите пункт Удалить.
Щелкните правой кнопкой мыши свойство CourseID типа сущности OnsiteCourse, а затем выберите пункт Удалить.
Выберите тип сущности Course. Установите свойство Абстрактный в значение true в окне Свойства.
Появляется окно с сообщением, что если задан абстрактный тип сущности, то все существующие сопоставления функции для данного типа сущности будут удалены. Нажмите кнопку ОК.
Примечание Теперь тип сущности Course изменен на абстрактный тип, поэтому функциональные возможности обновления первоначального приложения CourseManager перестают действовать. Щелкните правой кнопкой мыши тип сущности OnlineCourse и выберите пункт Сопоставление таблицы.
Появится окно Сведения о сопоставлении.
Щелкните поле Значение/Свойство, соответствующее столбцу CourseID.
Поле Значение/Свойство становится раскрывающимся списком свойств, доступных для сопоставления с соответствующим столбцом.
Выберите пункт CourseID из раскрывающегося списка.
Повторите шаги от 11 до 13 для типа сущности OnsiteCourse.
Теперь наследование типа «одна таблица на тип» реализовано.
Создание пользовательского интерфейса
Затем необходимо добавить кнопку к форме CourseViewer, которая загружает и отображает форму CourseDiscrimForm. Затем добавляются два элемента управления DataGridView для отображения OnsiteCourses и OnlineCourses. Наконец, будет выполнена привязка элементов управления DataGridView и BindingSource. Дополнительные сведения о привязке объектов к элементам управления см. в разделе Binding Objects to Controls (Entity Framework).
Создание пользовательского интерфейса
Щелкните правой кнопкой мыши имя проекта CourseManager в окне Обозреватель решений, укажите пункт Добавить, а затем выберите пункт Новый элемент.
Появится диалоговое окно Добавление нового элемента.
Выберите Форма Windows Forms, а затем нажмите кнопку Добавить.
Новая форма будет добавлена к проекту и открыта в конструкторе форм.
В окне Свойства назначьте форме имя CourseDiscriminator.
Новая форма будет добавлена к проекту и открыта в конструкторе форм. Форме назначается имя CourseDiscriminator и текст CourseDiscriminator.
Перетащите элемент управления ComboBox из области элементов в форму и назначьте ему имя departmentList в окне Свойства.
Перетащите элемент управления DataGridView из области элементов в форму и присвойте ему имя onsiteGridView.
Перетащите еще один элемент управления DataGridView из области элементов в форму и назначьте ему имя onlineGridView.
В окне Обозреватель решений дважды щелкните форму CourseViewer.cs или CourseViewer.vb.
Форма CourseViewer откроется в конструкторе.
Перетащите элемент управления Button из области элементов в форму CourseViewer.
В окне Свойства назначьте кнопке Button имя viewDiscriminator, а затем задайте для кнопки текст Online vs. Onsite.
Дважды щелкните viewDiscriminator Button.
Откроется файл с фоновым кодом для формы.
Добавьте следующий код в обработчик события viewDiscriminator_click:
Dim courseDiscrim As New CourseDiscriminator courseDiscrim.Visible = True
CourseDiscriminator courseDiscrim = new CourseDiscriminator(); courseDiscrim.Visible = true;
Теперь создание пользовательского интерфейса для этой формы завершено.
Выполнение запроса к концептуальной модели
В этой процедуре выполняется запрос к концептуальной модели, а результаты привязываются к элементам управления Windows Forms.
Запрос к концептуальной модели
Откройте форму CourseDiscriminator в конструкторе форм.
Перетащите элемент управления BindingSource из области элементов в форму.
В окне Свойства назначьте BindingSource имя onsiteBindingSource.
Щелкните поле рядом со свойством DataSource в окне Свойства.
Поле становится раскрывающимся списком доступных источников данных.
Нажмите кнопку Добавить источник данных проекта.
Откроется окно Выбор типа источника данных программы Мастер настройки источника данных.
В поле Источник данных для приложения выберите Объект.
Нажмите кнопку Далее.
Открывается окно Выбор объекта для привязки. Откроется верхний узел дерева доступных ресурсов.
Раскройте узел CourseManager, а затем дочерний узел CourseManager.
Выберите OnsiteCourse, а затем нажмите кнопку Готово.
Повторите шаги со 2 до 9, но назначьте элементу управления BindingSource имя OnlineBindingSource и выполните его привязку к объекту OnlineCourse.
Щелкните правой кнопкой мыши элемент управления OnsiteGridView и выберите пункт Свойства.
В окне Свойства щелкните поле рядом со свойством DataSource.
Поле становится раскрывающимся списком доступных источников данных.
Выберите OnsiteBindingSource.
Повторите шаги с 11 по 13 для OnlineGridView, но назначьте свойству DataSouce значение OnlineBindingSource.
Примечание Метод OfType возвращает перечисление, из которого элемент управления DataGridView не может сформировать столбцы во время выполнения.Чтобы отобразить нужные сведения в этом примере, источники данных для элементов управления DataGridView устанавливаются во время разработки через элементы управления BindingSource на основе классов, к которым нужно выполнить привязку. Дважды щелкните форму CourseDiscriminator.
Откроется файл с фоновым кодом для формы CourseDiscriminator.
Добавьте следующие инструкции using (C#) или Imports (Visual Basic), чтобы сослаться на модель, созданную из базы данных School, и пространство имен сущностей.
Imports System.Data.Objects Imports System.Data.Objects.DataClasses
using System.Data.Objects; using System.Data.Objects.DataClasses;
Добавьте свойство, которое представляет контекст данных, к классу CourseDiscriminator:
' Create an ObjectContext instance based on SchoolEntity. Private schoolContext As SchoolEntities
// Create an ObjectContext instance based on SchoolEntity. private SchoolEntities schoolContext;
В обработчике события CourseDiscriminator_Load добавьте код для инициализации контекста объекта и выполните привязку элемента управления departmentList к запросу, который возвращает сведения Department.
' Initialize the ObjectContext. schoolContext = New SchoolEntities() ' Define a query that returns all Department objects and ' related Course objects, ordered by name. Dim departmentQuery As ObjectQuery(Of Department) = _ schoolContext.Departments.Include("Courses").OrderBy("it.Name") ' Bind the ComboBox control to the query, which is ' executed during data binding. departmentList.DisplayMember = "Name" departmentList.DataSource = departmentQuery. _ Execute(MergeOption.OverwriteChanges)
// Initialize the ObjectContext. schoolContext = new SchoolEntities(); // Define a query that returns all Department objects // and related Course objects, ordered by name. ObjectQuery<Department> departmentQuery = schoolContext.Departments.Include("Courses"). OrderBy("it.Name"); // Bind the ComboBox control to the query. this.departmentList.DisplayMember = "Name"; this.departmentList.DataSource = departmentQuery. Execute(MergeOption.OverwriteChanges);
Возвратитесь к конструктору формы CourseDiscriminator и дважды щелкните элемент управления departmentList ComboBox.
Откроется файл с фоновым кодом. В код был добавлен обработчик события departmentList_SelectedIndexChanged.
Добавьте следующий код в обработчик события departmentList_SelectedIndexChanged, чтобы обновить источники данных для элементов управления BindingSource.
' Get the selected department object. Dim department As Department = CType(Me.departmentList. _ SelectedItem, Department) ' Update the data sources for the BindingSource controls. onsiteBindingSource.DataSource = department.Courses _ .OfType(Of OnsiteCourse)() onlineBindingSource.DataSource = department.Courses _ .OfType(Of OnlineCourse)()
// Get the selected department object. Department department = (Department)this.departmentList .SelectedItem; // Update the data sources for the BindingSource controls. onsiteBindingSource.DataSource = department.Courses. OfType<OnsiteCourse>(); onlineBindingSource.DataSource = department.Courses. OfType<OnlineCourse>();
Создание приложения завершено. Нажмите клавиши Ctrl+F5, чтобы запустить приложение. Нажмите кнопку Onsite vs. Online, чтобы загрузить форму CourseDiscriminator. Значения OnsiteCourses и OnlineCourses для выбранного отдела отображаются в элементах управления DataGridView
Листинг кода
В этом разделе содержится окончательная версия файла с фоновым кодом для формы CourseDiscriminator.
Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class CourseDiscriminator
' Create an ObjectContext instance based on SchoolEntity.
Private schoolContext As SchoolEntities
Private Sub CourseDiscriminator_Load(ByVal sender As System. _
Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Initialize the ObjectContext.
schoolContext = New SchoolEntities()
' Define a query that returns all Department objects and
' related Course objects, ordered by name.
Dim departmentQuery As ObjectQuery(Of Department) = _
schoolContext.Departments.Include("Courses").OrderBy("it.Name")
' Bind the ComboBox control to the query, which is
' executed during data binding.
departmentList.DisplayMember = "Name"
departmentList.DataSource = departmentQuery. _
Execute(MergeOption.OverwriteChanges)
End Sub
Private Sub departmentList_SelectedIndexChanged(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
departmentList.SelectedIndexChanged
' Get the selected department object.
Dim department As Department = CType(Me.departmentList. _
SelectedItem, Department)
' Update the data sources for the BindingSource controls.
onsiteBindingSource.DataSource = department.Courses _
.OfType(Of OnsiteCourse)()
onlineBindingSource.DataSource = department.Courses _
.OfType(Of OnlineCourse)()
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 CourseDiscriminator : Form
{
// Create an ObjectContext instance based on SchoolEntity.
private SchoolEntities schoolContext;
public CourseDiscriminator()
{
InitializeComponent();
}
private void CourseDiscriminator_Load(object sender,
EventArgs e)
{
// Initialize the ObjectContext.
schoolContext = new SchoolEntities();
// Define a query that returns all Department objects
// and related Course objects, ordered by name.
ObjectQuery<Department> departmentQuery =
schoolContext.Departments.Include("Courses").
OrderBy("it.Name");
// Bind the ComboBox control to the query.
this.departmentList.DisplayMember = "Name";
this.departmentList.DataSource = departmentQuery.
Execute(MergeOption.OverwriteChanges);
}
private void departmentList_SelectedIndexChanged(object sender,
EventArgs e)
{
// Get the selected department object.
Department department = (Department)this.departmentList
.SelectedItem;
// Update the data sources for the BindingSource controls.
onsiteBindingSource.DataSource = department.Courses.
OfType<OnsiteCourse>();
onlineBindingSource.DataSource = department.Courses.
OfType<OnlineCourse>();
}
}
}
Следующие шаги
Наследование типа «одна таблица на тип» в концептуальной модели реализовано успешно. Дополнительные сведения о способах определения концептуальной модели с наследованием типа «одна таблица на тип» см. в разделе How to: Define a Model with Table-per-Type Inheritance. Дополнительные сведения о построении приложений, использующих платформу Entity Framework, см. в разделе ADO.NET Entity Framework.
См. также
Другие ресурсы
Сценарии средств работы с моделью EDM
Задачи средств модели EDM