Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Пример веб-приложения Contoso University демонстрирует создание приложений веб-форм ASP.NET с помощью Entity Framework 4.0 и Visual Studio 2010. Сведения о серии учебников см. в первом руководстве в серии
Реализация наследования таблиц на иерархию
В предыдущем руководстве вы работали с связанными данными, добавляя и удаляя связи и добавляя новую сущность, которая имела связь с существующей сущностью. В этом руководстве показано, как реализовать наследование в модели данных.
В объектно-ориентированном программировании можно использовать наследование, чтобы упростить работу со связанными классами. Например, можно создать классы Instructor и Student, производные от Person базового класса. Вы можете создать те же типы структур наследования между сущностями в Entity Framework.
В этой части руководства вы не создадите новые веб-страницы. Вместо этого вы добавите производные сущности в модель данных и измените существующие страницы для использования новых сущностей.
Наследование таблиц на уровне иерархии и таблицы на тип
База данных может хранить сведения о связанных объектах в одной таблице или в нескольких таблицах. Например, в School базе данных Person таблица содержит сведения о учащихся и инструкторах в одной таблице. Некоторые из столбцов применяются только к инструкторам (), некоторые только учащимся (HireDateEnrollmentDate), а некоторые — к обоим (LastName, FirstName).
Вы можете настроить Entity Framework для создания Instructor и Student сущностей, наследующих от сущности Person . Этот шаблон создания структуры наследования сущностей из одной таблицы базы данных называется наследованием таблицы на уровне иерархии (TPH).
Для курсов School база данных использует другой шаблон. Онлайн-курсы и курсы на сайте хранятся в отдельных таблицах, каждый из которых имеет внешний ключ, указывающий на таблицу Course . Сведения, общие для обоих типов курсов, хранятся только в Course таблице.
Модель данных Entity Framework можно настроить таким образом, чтобы OnlineCourse и OnsiteCourse сущности наследуются от сущности Course . Этот шаблон создания структуры наследования сущностей из отдельных таблиц для каждого типа, где каждая отдельная таблица ссылается обратно на таблицу, которая хранит данные, общие для всех типов, называется наследованием таблица на каждый тип (TPT).
Шаблоны наследования TPH обычно обеспечивают лучшую производительность в Entity Framework, чем шаблоны наследования TPT, так как шаблоны TPT могут привести к сложным запросам соединения. В этом руководстве показано, как реализовать наследование типа TPH. Для этого выполните следующие действия:
- Создайте типы сущностей
InstructorиStudent, производные отPerson. - Перемещение свойств, относящихся к производным сущностям от
Personсущности, к производным сущностям. - Задайте ограничения свойств в производных типах.
-
PersonСделайте сущность абстрактной сущностью. - Сопоставляйте каждую производную сущность с
Personтаблицей с условием, определяющим, представляет лиPersonстрока производный тип.
Добавление сущностей преподавателя и учащихся
Откройте файл SchoolModel.edmx , щелкните правой кнопкой мыши не занятую область в конструкторе, выберите "Добавить", а затем выберите "Сущность".
В диалоговом окне "Добавление сущности" назовите сущность Instructor и задайте для нее значение Person".
Нажмите кнопку ОК. Конструктор создает сущность Instructor, которая наследуется от сущности Person. Новая сущность пока не имеет никаких свойств.
Повторите процедуру, чтобы создать сущность, которая наследуется как от Student, так и от Person.
Только инструкторы имеют даты найма, поэтому необходимо переместить это свойство из Person сущности в Instructor сущность. В сущности Person, щелкните правой кнопкой мыши на свойстве HireDate и нажмите Вырезать. Затем щелкните правой кнопкой мыши свойства в сущности Instructor и нажмите кнопку "Вставить".
Дата найма для сущности Instructor не может быть нулевой. Щелкните правой кнопкой мыши HireDate свойство, выберите Свойства, а затем в окне Свойства измените Nullable на False.
Повторите процедуру, чтобы переместить EnrollmentDate свойство из Person сущности в Student сущность. Убедитесь, что для свойства также задано значение NullableFalseEnrollmentDate .
Теперь, когда Person сущность имеет только те свойства, которые являются общими для Instructor и Student сущностей (за исключением свойств навигации, которые вы не изменяете), сущность может использоваться только как базовая сущность в иерархии наследования. Поэтому необходимо убедиться, что он никогда не рассматривается как независимая сущность. Щелкните правой кнопкой мыши Person сущность, выберите "Свойства", а затем в окне "Свойства " измените значение свойства Abstract на True.
Сопоставление сущностей инструктора и студентов с таблицей Person
Теперь необходимо сообщить Entity Framework, как различать сущности InstructorStudent в базе данных.
Щелкните правой Instructor кнопкой мыши сущность и выберите "Сопоставление таблиц". В окне сведений о сопоставлении нажмите кнопку "Добавить таблицу" или "Вид" и выберите "Человек".
Нажмите Добавить условие и выберите HireDate.
Измените операторis и value / Property на Not Null.
Повторите процедуру для Students сущности, указав, что эта сущность сопоставляется с таблицей Person , если EnrollmentDate столбец не имеет значения NULL. Затем сохраните и закройте модель данных.
Создайте проект, чтобы создать новые сущности в качестве классов и сделать их доступными в конструкторе.
Использование сущностей инструктора и учащихся
Когда вы создавали веб-страницы для работы с данными студентов и преподавателей, вы связывали их с набором сущностей Person и фильтровали данные по свойству HireDate или EnrollmentDate, чтобы ограничить возвращенную информацию студентами или преподавателями. Однако теперь при привязке каждого элемента управления источниками данных к набору Person сущностей можно указать, что следует выбрать только типы сущностей Student или Instructor. Поскольку Entity Framework знает, как различать студентов и преподавателей в наборе сущностей Person, можно удалить настройки свойств Where, введенные вручную.
В конструкторе Visual Studio можно указать тип сущности, который EntityDataSource элемент управления должен выбрать в раскрывающемся списке Configure Data Source мастера, как показано в следующем примере.
В окне "Свойства" можно удалить Where значения предложений, которые больше не нужны, как показано в следующем примере.
Тем не менее, так как вы изменили разметку для элементов управления, чтобы использовать атрибут ContextTypeName, вы не можете запустить мастер Настройка источника данных для EntityDataSource уже созданных элементов управления. Поэтому необходимо внести необходимые изменения, изменив разметку.
Откройте страницу Students.aspx . В элементе StudentsEntityDataSource управления удалите Where атрибут и добавьте EntityTypeFilter="Student" атрибут. Теперь разметка будет выглядеть следующим образом:
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People" EntityTypeFilter="Student"
Include="StudentGrades"
EnableDelete="True" EnableUpdate="True"
OrderBy="it.LastName" >
</asp:EntityDataSource>
EntityTypeFilter Установка атрибута гарантирует, что EntityDataSource элемент управления выбирает только указанный тип сущности. Если вы хотите получить оба Student типа и Instructor типы сущностей, этот атрибут не будет задан. (Вы можете получить несколько типов сущностей с одним EntityDataSource элементом управления, только если вы используете элемент управления для доступа к данным только для чтения. Если вы используете элемент управления для вставки, обновления или удаления сущностей, и если набор сущностей, к которым он привязан, может содержать несколько типов, вы можете работать только с одним типом EntityDataSource сущности, и необходимо задать этот атрибут.)
Повторите процедуру для элемента управления SearchEntityDataSource, но удалите только ту часть атрибута Where, которая выбирает сущности Student, вместо удаления свойства полностью. Открывающий тег элемента управления теперь будет выглядеть следующим образом:
<asp:EntityDataSource ID="SearchEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People" EntityTypeFilter="Student"
Where="it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%'" >
Запустите страницу, чтобы убедиться, что она по-прежнему работает, как и раньше.
Обновите следующие страницы, созданные в предыдущих руководствах, чтобы они использовали новые Student и Instructor сущности вместо Person сущностей, а затем запустите их, чтобы убедиться, что они работают, как и раньше:
В StudentsAdd.aspx добавьте
EntityTypeFilter="Student"вStudentsEntityDataSourceэлемент управления. Теперь разметка будет выглядеть следующим образом:<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Student" EnableInsert="True" </asp:EntityDataSource>В About.aspx добавьте элемент управления
StudentStatisticsEntityDataSourceи удалитеWhere="it.EnrollmentDate is not null"его. Теперь разметка будет выглядеть следующим образом:<asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Student" Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents" OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate" > </asp:EntityDataSource>В Instructors.aspx и InstructorsCourses.aspx добавьте
EntityTypeFilter="Instructor"вInstructorsEntityDataSourceэлемент управления и удалитеWhere="it.HireDate is not null"его. Разметка в Instructors.aspx теперь похожа на следующий пример:<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false" EntitySetName="People" EntityTypeFilter="Instructor" Include="OfficeAssignment" EnableUpdate="True"> </asp:EntityDataSource>Разметка в InstructorsCourses.aspx теперь будет выглядеть следующим образом:
<asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" EntitySetName="People" EntityTypeFilter="Instructor" Select="it.LastName + ',' + it.FirstMidName AS Name, it.PersonID"> </asp:EntityDataSource>
В результате этих изменений вы улучшили поддержку приложения Contoso University несколькими способами. Вы переместили логику выбора и проверки из слоя пользовательского интерфейса (.aspx разметку) и сделали ее неотъемлемой частью уровня доступа к данным. Это помогает изолировать код приложения от изменений, которые можно внести в будущем в схему базы данных или модель данных. Например, вы можете решить, что учащиеся могут быть наняты в качестве помощников учителей и поэтому получить дату найма. Затем можно добавить новое свойство, чтобы отличить учащихся от преподавателей и обновить модель данных. Код в веб-приложении не должен меняться, за исключением того, где вы хотите показать дату найма для учащихся. Еще одним преимуществом добавления Instructor и Student сущностей является то, что код становится более легко воспринимаемым, чем когда он ссылается на Person объекты, представляющие собой учащихся или инструкторов.
Теперь вы видели один из способов реализации шаблона наследования в Entity Framework. В следующем руководстве вы узнаете, как использовать хранимые процедуры, чтобы иметь больше контроля над доступом Entity Framework к базе данных.