Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Пример веб-приложения Contoso University демонстрирует создание приложений веб-форм ASP.NET с помощью Entity Framework 4.0 и Visual Studio 2010. Сведения о серии учебников см. в первом руководстве в серии
Элемент управления EntityDataSource
В предыдущем руководстве вы создали веб-сайт, базу данных и модель данных. В этом руководстве вы работаете с EntityDataSource элементом управления, который ASP.NET предоставляет, чтобы упростить работу с моделью данных Entity Framework. Вы создадите GridView элемент управления для отображения и редактирования данных учащихся, DetailsView элемента управления для добавления новых учащихся и DropDownList элемента управления для выбора отдела (который будет использоваться позже для отображения связанных курсов).
Обратите внимание, что в этом приложении вы не будете добавлять проверку входных данных на страницы, которые обновляют базу данных, и некоторые аспекты обработки ошибок не будут столь надежными, как это требуется в рабочем приложении. Это позволяет учебнику сосредоточиться на Entity Framework и предотвращает его чрезмерное удлинение. Дополнительные сведения о добавлении этих функций в приложение см. в разделах "Проверка входных данных пользователей в ASP.NET веб-страницах" и "Обработка ошибок в ASP.NET страницах и приложениях".
Добавление и настройка элемента управления EntityDataSource
Сначала вы настроите EntityDataSource элемент управления для чтения Person сущностей из People набора сущностей.
Убедитесь, что у вас открыта Visual Studio, и вы работаете с проектом, созданным в части 1. Если вы не создали проект с момента создания модели данных или с момента последнего изменения, которое вы внесли в него, создайте проект. Изменения модели данных не становятся доступными конструктору, пока проект не будет создан.
Создайте новую веб-страницу с помощью шаблона главной страницы и назовите ее Students.aspx.
Укажите Site.Master в качестве главной страницы. Все страницы, создаваемые для этих учебников, будут использовать эту главную страницу.
В представлении источника добавьте h2 заголовок в Content элемент управления с именем Content2, как показано в следующем примере:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
</asp:Content>
На вкладке "Данныепанели элементов перетащите EntityDataSource элемент управления на страницу, переместите его под заголовок и измените идентификатор на StudentsEntityDataSource:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server">
</asp:EntityDataSource>
</asp:Content>
Переключитесь на вид Дизайн, щелкните смарт-тег элемента управления источником данных и нажмите Настроить источник данных, чтобы запустить мастер Настройка источника данных.
На шаге мастера настройки ObjectContext выберите SchoolEntities в качестве значения для Named Connection и выберите SchoolEntities в качестве значения для DefaultContainerName. Затем нажмите кнопку "Далее".
Примечание. Если вы получите следующее диалоговое окно на этом этапе, необходимо создать проект, прежде чем продолжить.
На шаге "Настройка выбора данных" выберите "Люди " в качестве значения EntitySetName. В разделе "Выбрать" убедитесь, что установлен флажок "Выбрать всё". Затем выберите параметры для включения обновления и удаления. По завершении нажмите кнопку "Готово".
Настройка правил базы данных для разрешения удаления
Вы создадите страницу, которая позволяет пользователям удалять учащихся из Person таблицы, которая имеет три связи с другими таблицами (Course, StudentGradeи ).OfficeAssignment По умолчанию база данных не позволит удалить строку, Person если в одной из других таблиц есть связанные строки. Сначала можно удалить связанные строки вручную или настроить базу данных для автоматического их удаления при удалении Person строки. Для записей учащихся в этом руководстве вы настроите базу данных для автоматического удаления связанных данных. Так как учащиеся могут иметь связанные строки только в StudentGrade таблице, необходимо настроить только одну из трех связей.
Если вы используете School.mdf файл, скачанный из проекта, который идет с этим руководством, можно пропустить этот раздел, так как эти изменения конфигурации уже выполнены. Если база данных создана путем выполнения скрипта, настройте базу данных, выполнив следующие процедуры.
В обозревателе серверов откройте схему базы данных, созданную в части 1. Щелкните правой кнопкой мыши по отношению между Person и StudentGrade (линия между таблицами), а затем выберите Свойства.
В окне "Свойства" разверните спецификацию INSERT и UPDATE и задайте для свойства DeleteRule значение Cascade.
Сохраните и закройте схему. Если вы хотите обновить базу данных, нажмите кнопку "Да".
Чтобы убедиться, что модель синхронизирует сущности в памяти с операциями базы данных, необходимо задать соответствующие правила в модели данных. Откройте SchoolModel.edmx, щелкните правой кнопкой мыши линию связи между Person и StudentGradeвыберите пункт "Свойства".
В окне свойств задайте для End1 OnDelete значение Cascade.
Сохраните и закройте файл SchoolModel.edmx , а затем перестроите проект.
Как правило, при изменении базы данных у вас есть несколько вариантов синхронизации модели:
- Для определенных типов изменений (например, добавление или обновление таблиц, представлений или хранимых процедур) щелкните правой кнопкой мыши в конструкторе и выберите "Обновить модель из базы данных ", чтобы конструктор автоматически вносит изменения.
- Повторно создайте модель данных.
- Сделайте такие обновления вручную.
В этом случае вы могли бы заново создать модель или обновить таблицы, затронутые изменением связи, но затем вам пришлось бы снова изменить имя поля с FirstName на FirstMidName.
Использование элемента управления GridView для чтения и обновления сущностей
В этом разделе вы будете использовать GridView элемент управления для отображения, обновления или удаления учащихся.
Откройте или переключитесь на Students.aspx и перейдите в режим конструктора . На вкладке Данныепанели элементов перетащите элемент управления GridView справа от элемента управления EntityDataSource, назовите его StudentsGridView, щелкните смарт-тег и выберите StudentsEntityDataSource в качестве источника данных.
Щелкните "Обновить схему " (нажмите кнопку "Да" , если вам будет предложено подтвердить), а затем нажмите кнопку "Включить разбиение по страницам", "Включить сортировку", "Включить редактирование" и "Включить удаление".
Нажмите кнопку "Изменить столбцы".
В поле "Выбранные поля " удалите PersonID, LastName и HireDate. Как правило, вы не показываете ключ записи пользователям, так как дата найма не имеет значения для студентов, и вы будете объединять обе части имени в одно поле, поэтому потребуется только одно поле для имени.
Выберите поле FirstMidName и нажмите кнопку Преобразовать это поле в TemplateField.
Выполните то же самое для EnrollmentDate.
Нажмите кнопку "ОК ", а затем перейдите в представление источника . Остальные изменения будут проще выполнять непосредственно в разметке. Разметка GridView элемента управления теперь выглядит следующим образом.
<asp:GridView ID="StudentsGridView" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="PersonID"
DataSourceID="StudentsEntityDataSource">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:TemplateField HeaderText="FirstMidName" SortExpression="FirstMidName">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="EnrollmentDate" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Первый столбец после поля команды — это поле шаблона, которое в настоящее время отображает имя. Измените разметку для этого поля шаблона, чтобы выглядеть следующим образом:
<asp:TemplateField HeaderText="Name" SortExpression="LastName">
<EditItemTemplate>
<asp:TextBox ID="LastNameTextBox" runat="server" Text='<%# Bind("LastName") %>'></asp:TextBox>
<asp:TextBox ID="FirstNameTextBox" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Два элемента управления Label в режиме отображения отображают имя и фамилию. В режиме редактирования предоставляются два текстовых поля, чтобы изменить имя и фамилию. Как и Label элементы управления в режиме отображения, Bind и Eval выражения используются точно так же, как элементы управления источниками данных в ASP.NET, которые подключаются непосредственно к базам данных. Единственное различие заключается в том, что вы указываете свойства сущности вместо столбцов базы данных.
Последний столбец — это поле шаблона, отображающее дату регистрации. Измените разметку для этого поля, чтобы выглядеть следующим образом:
<asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="EnrollmentDateTextBox" runat="server" Text='<%# Bind("EnrollmentDate", "{0:d}") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="EnrollmentDateLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
В режиме отображения и редактирования строка формата "{0,d}" приводит к отображению даты в формате short date. (Компьютер может быть настроен для отображения этого формата по-разному от изображений экрана, показанных в этом руководстве.)
Обратите внимание, что в каждом из этих полей шаблона конструктор использовал Bind выражение по умолчанию, но вы изменили его на Eval выражение в элементах ItemTemplate . Выражение Bind делает данные доступными в GridView свойствах элемента управления, если необходимо получить доступ к данным в коде. На этой странице не требуется получать доступ к этим данным в коде, поэтому вы можете использовать Eval, что более эффективно. Дополнительные сведения см. в статье "Получение данных из элементов управления данными".
Изменение разметки элемента управления EntityDataSource для повышения производительности
В разметке элемента управления EntityDataSource, удалите атрибуты ConnectionString и DefaultContainerName, заменив их на атрибут ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Это изменение следует вносить каждый раз, когда вы создаете EntityDataSource элемент управления, если только вам не нужно использовать соединение, отличное от жестко закодированного в классе контекста объекта. Использование атрибута ContextTypeName обеспечивает следующие преимущества:
- Улучшенная производительность.
EntityDataSourceКогда элемент управления инициализирует модель данных, используя атрибутыConnectionStringиDefaultContainerName, он выполняет дополнительную работу для загрузки метаданных при каждом запросе. Это не обязательно, если указатьContextTypeNameатрибут. - Отложенная загрузка включена по умолчанию в классах контекста созданных объектов (например
SchoolEntities, в этом руководстве) в Entity Framework 4.0. Это означает, что свойства навигации загружаются автоматически со связанными данными, когда это необходимо. В этом руководстве отложенная загрузка объясняется более подробно позже. - Все настройки, примененные к классу контекста объекта (в данном случае, классу
SchoolEntities), будут доступны для элементов управления, использующих элемент управленияEntityDataSource. Настройка класса контекста объекта — это расширенный раздел, который не рассматривается в этой серии руководств. Дополнительные сведения см. в разделе "Расширение созданных типов Entity Framework".
Теперь разметка будет похожа на следующий пример (порядок свойств может отличаться):
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
EnableDelete="True" EnableUpdate="True">
</asp:EntityDataSource>
Атрибут EnableFlattening ссылается на функцию, необходимую в более ранних версиях Entity Framework, так как внешние ключевые столбцы не были предоставлены как свойства сущности. Текущая версия позволяет использовать связи внешнего ключа, что означает, что свойства внешнего ключа предоставляются для всех, кроме связей "многие ко многим". Если у сущностей есть свойства внешнего ключа и нет сложных типов, этот атрибут можно оставить равным False. Не удаляйте атрибут из разметки, так как значение по умолчанию — True. Дополнительные сведения см. в разделе "Неструктурированные объекты" (EntityDataSource).
Запустите страницу и вы увидите список учащихся и сотрудников (вы будете фильтровать только учащихся в следующем руководстве). Имя и фамилия отображаются вместе.
Чтобы отсортировать отображение, щелкните имя столбца.
Щелкните "Изменить " в любой строке. Текстовые поля отображаются, где можно изменить имя и фамилию.
Кнопка "Удалить " также работает. Щелкните "Удалить" для строки с датой регистрации, и строка исчезнет. (Строки без даты регистрации представляют инструкторов, и вы можете получить ошибку целостности ссылок. В следующем руководстве вы отфильтруете этот список, чтобы включить только учащихся.)
Отображение данных из свойства навигации
Теперь предположим, что вы хотите узнать, сколько курсов каждый учащийся регистрируется. Entity Framework предоставляет эти сведения в свойстве навигации StudentGrades сущности Person. Так как структура базы данных не позволяет студенту быть зачисленным на курс без присвоения оценки, в этом руководстве можно предположить, что наличие строки в таблице StudentGrade, связанной с курсом, эквивалентно зачислению на курс. (Свойство Courses навигации предназначено только для преподавателей.)
При использовании ContextTypeName атрибута EntityDataSource элемента управления Entity Framework автоматически извлекает сведения для свойства навигации при доступе к такому свойству. Это называется отложенной загрузкой. Однако это может быть неэффективно, так как он приводит к отдельному вызову базы данных каждый раз, когда требуется дополнительная информация. Если вам нужны данные из свойства навигации для каждой сущности, возвращаемой EntityDataSource элементом управления, более эффективно получить связанные данные вместе с самой сущностью в одном вызове базы данных. Это называется жадной загрузкой, и вы указываете жадную загрузку для свойства навигации, задав свойство элемента управления EntityDataSource.
В Students.aspx вы хотите показать количество курсов для каждого учащегося, поэтому жадная загрузка является лучшим выбором. Если вы отображали всех учащихся, но отображали количество курсов только для нескольких из них (что потребует написания кода в дополнение к разметке), отложенная загрузка может быть лучшим выбором.
Откройте или переключитесь на Students.aspx, перейдите в режим конструктора , выберите StudentsEntityDataSourceи в окне "Свойства " задайте для свойства Include значение StudentGrades. (Если вы хотите получить несколько свойств навигации, можно указать имена, разделенные запятыми, например StudentGrades, Courses.)
Переключите в режим исходного кода. В элементе StudentsGridView управления после последнего asp:TemplateField элемента добавьте новое поле следующего шаблона:
<asp:TemplateField HeaderText="Number of Courses">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("StudentGrades.Count") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
В выражении Eval можно ссылаться на свойство навигации StudentGrades. Так как это свойство содержит коллекцию, оно имеет Count свойство, которое можно использовать для отображения количества курсов, в которых зарегистрирован учащийся. В следующем руководстве вы узнаете, как отображать данные из свойств навигации, содержащих отдельные сущности вместо коллекций. (Обратите внимание, что нельзя использовать BoundField элементы для отображения данных из свойств навигации.)
Откройте страницу, и вы увидите, на сколько курсов записан каждый студент.
Использование элемента управления DetailsView для вставки сущностей
Следующий шаг — создать страницу с элементом DetailsView управления, который позволит добавить новых учащихся. Закройте браузер и создайте новую веб-страницу с помощью главной страницы Site.Master . Назовите страницу StudentsAdd.aspx, а затем перейдите в представление источника .
Добавьте следующую разметку, чтобы заменить существующую разметку для Content элемента управления с именем Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Add New Students</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EnableInsert="True" EntitySetName="People">
</asp:EntityDataSource>
<asp:DetailsView ID="StudentsDetailsView" runat="server"
DataSourceID="StudentsEntityDataSource" AutoGenerateRows="False"
DefaultMode="Insert">
<Fields>
<asp:BoundField DataField="FirstMidName" HeaderText="First Name"
SortExpression="FirstMidName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name"
SortExpression="LastName" />
<asp:BoundField DataField="EnrollmentDate" HeaderText="Enrollment Date"
SortExpression="EnrollmentDate" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
</asp:Content>
Эта разметка создает элемент управления, который аналогичен созданному в Students.aspxEntityDataSource, за исключением возможности вставки. Как и в GridView случае с элементом управления, привязанные поля DetailsView элемента управления кодируются точно так же, как и для элемента управления данными, который подключается непосредственно к базе данных, за исключением того, что они ссылаются на свойства сущности. В этом случае DetailsView элемент управления используется только для вставки строк, поэтому режим Insertпо умолчанию установлен.
Запустите страницу и добавьте нового учащегося.
Ничего не произойдет после вставки нового учащегося, но если вы теперь запускаете Students.aspx, вы увидите новые сведения о учащихся.
Отображение данных в выпадающем списке
В следующих шагах вы свяжите элемент управления DropDownList с набором сущностей, используя элемент управления EntityDataSource. В этой части руководства вы не будете много делать с этим списком. Однако в последующих частях вы будете использовать список, чтобы позволить пользователям выбрать отдел для отображения курсов, связанных с отделом.
Создайте новую веб-страницу с именем Courses.aspx. В представлении источника добавьте заголовок в Content элемент управления с именем Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Courses by Department</h2>
</asp:Content>
В режиме конструктора добавьте элемент управления на страницу, как и раньше, но на этот раз назовите его DepartmentsEntityDataSource. Выберите "Отделы " в качестве значения EntitySetName и выберите только свойства DepartmentID и Name .
На вкладке "Стандартный " панели элементов перетащите DropDownList элемент управления на страницу, назовите его DepartmentsDropDownList, щелкните смарт-тег и выберите "Выбрать источник данных ", чтобы запустить мастер настройки источника данных.
На шаге "Выбор источника данных " выберите DepartmentEntityDataSource в качестве источника данных, щелкните "Обновить схему", а затем выберите "Имя " в качестве поля данных для отображения и departmentID в качестве поля данных значения. Нажмите кнопку ОК.
Метод, используемый для привязки элемента управления с помощью Entity Framework, совпадает с другими элементами управления источниками данных ASP.NET, за исключением указания сущностей и свойств сущностей.
Перейдите в представление источника и добавьте команду "Выбрать отдел:" непосредственно перед элементом DropDownList управления.
Select a department:
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="EntityDataSource1" DataTextField="Name"
DataValueField="DepartmentID">
</asp:DropDownList>
Как напоминание, измените разметку элемента EntityDataSource управления на этом этапе, заменив атрибуты ConnectionString и DefaultContainerName на атрибут ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Часто рекомендуется ждать, пока вы создадите элемент управления с привязкой к данным, связанный с элементом управления источником данных, прежде чем изменять EntityDataSource разметку элемента управления, так как после внесения изменений конструктор не предоставит параметр "Обновить схему " в элементе управления с привязкой к данным.
Запустите страницу и выберите отдел из раскрывающегося списка.
Это завершает введение в использование элемента управления EntityDataSource. Работа с этим элементом управления обычно не отличается от работы с другими элементами управления источниками данных ASP.NET, за исключением того, что вы ссылаетесь на сущности и свойства вместо таблиц и столбцов. Единственным исключением является доступ к свойствам навигации. В следующем руководстве вы увидите, что синтаксис, используемый с элементом управления, EntityDataSource также может отличаться от других элементов управления источниками данных при фильтрации, группировке и заказе данных.