Поделиться через


начало работы с entity Framework 4.0 Database First и ASP.NET 4 веб-формы — часть 2

Том Дайкстра

Пример веб-приложения Contoso University демонстрирует создание ASP.NET Web Forms приложений с помощью 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.

Изображение23

Укажите Site.Master в качестве страницы master. Все страницы, создаваемые для этих учебников, будут использовать эту страницу master.

Изображение 24

В представлении исходного кода добавьте заголовок 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>

Перейдите в режим конструктора , щелкните смарт-тег элемента управления источником данных и щелкните Настроить источник данных , чтобы запустить мастер настройки источника данных .

Изображение01

На шаге мастера Настройка ObjectContext выберите SchoolEntities в качестве значения именованного подключения, а в качестве значения DefaultContainerName выберите SchoolEntities. Нажмите кнопку Далее.

Image02

Примечание. Если на этом этапе появится следующее диалоговое окно, необходимо выполнить сборку проекта, прежде чем продолжить.

Изображение25

На шаге Настройка выбора данных выберите Люди в качестве значения EntitySetName. В разделе Выбрать убедитесь, что выбрано поле Выбрать проверка. Затем выберите параметры для включения обновления и удаления. Когда все будет готово, нажмите кнопку Готово.

Image03

Настройка правил базы данных для разрешения удаления

Вы создадите страницу, которая позволяет пользователям удалять учащихся из Person таблицы, которая имеет три связи с другими таблицами (Course, StudentGradeи OfficeAssignment). По умолчанию база данных не позволяет удалить строку в Person , если в одной из других таблиц есть связанные строки. Вы можете сначала вручную удалить связанные строки или настроить для базы данных автоматическое удаление их при удалении Person строки. Для записей учащихся в этом руководстве вы настроите базу данных для автоматического удаления связанных данных. Так как учащиеся могут иметь связанные строки только в StudentGrade таблице, необходимо настроить только одну из трех связей.

Если вы используете файл School.mdf , скачанный из проекта, который входит в это руководство, этот раздел можно пропустить, так как эти изменения конфигурации уже выполнены. Если вы создали базу данных с помощью скрипта, настройте ее, выполнив следующие процедуры.

В Обозреватель сервера откройте схему базы данных, созданную в части 1. Щелкните правой кнопкой мыши связь между Person и StudentGrade (линия между таблицами), а затем выберите Свойства.

Image04

В окне Свойства разверните инструкции INSERT и UPDATE Specification и задайте для свойства DeleteRule значение Каскад.

Image05

Сохраните и закройте схему. Если вам будет предложено обновить базу данных, нажмите кнопку Да.

Чтобы убедиться, что модель сохраняет сущности, которые находятся в памяти, синхронизированы с тем, что делает база данных, необходимо задать соответствующие правила в модели данных. Откройте SchoolModel.edmx, щелкните правой кнопкой мыши линию связи между Person и StudentGrade, а затем выберите Свойства.

Изображение21

В окне Свойства задайте для end1 OnDelete значение Каскад.

Изображение 22

Сохраните и закройте файл SchoolModel.edmx , а затем перестройте проект.

Как правило, при изменении базы данных можно синхронизировать модель несколькими способами:

  • Для некоторых типов изменений (например, добавления или обновления таблиц, представлений или хранимых процедур) щелкните правой кнопкой мыши конструктор и выберите Обновить модель из базы данных , чтобы конструктор автоматически внесет изменения.
  • Повторно создайте модель данных.
  • Внесите обновления вручную, как это.

В этом случае вы могли бы повторно создать модель или обновить таблицы, затронутые изменением связи, но затем потребуется снова изменить имя поля (с FirstName на FirstMidName).

Использование элемента управления GridView для чтения и обновления сущностей

В этом разделе вы будете GridView использовать элемент управления для отображения, обновления или удаления учащихся.

Откройте файл Students.aspx или перейдите в режим конструктора . На вкладке Данныепанели элементов перетащите GridView элемент управления справа от EntityDataSource элемента управления, назовите его StudentsGridView, щелкните смарт-тег и выберите StudentsEntityDataSource в качестве источника данных.

Image06

Щелкните Обновить схему (нажмите кнопку Да , если появится запрос на подтверждение), а затем выберите Включить разбиение по страницам, Включить сортировку, Включить редактирование и Включить удаление.

Щелкните Изменить столбцы.

Изображение10

В поле Выбранные поля удалите PersonID, LastName и HireDate. Как правило, ключ записи не отображается для пользователей, дата найма не относится к учащимся, и вы помещаете обе части имени в одно поле, поэтому вам потребуется только одно из полей имени.)

Изображение11

Выберите поле FirstMidName и щелкните Преобразовать это поле в TemplateField.

Сделайте то же самое для EnrollmentDate.

Изображение13

Нажмите кнопку ОК , а затем переключитесь в исходное представление. Остальные изменения будет проще выполнять непосредственно в разметке. Разметка 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 управления в режиме отображения, выражения и Eval используются Bind точно так же, как и в 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}" приводит к отображению даты в формате "краткая дата". (На компьютере может быть настроено отображение этого формата, отличного от изображений экрана, показанных в этом руководстве.)

Обратите внимание, что в каждом из этих полей шаблона конструктор использовал 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).

Запустите страницу, и вы увидите список учащихся и сотрудников (вы будете фильтровать только учащихся в следующем руководстве). Имя и фамилия отображаются вместе.

Изображение07

Чтобы отсортировать отображение, щелкните имя столбца.

Щелкните Изменить в любой строке. Отображаются текстовые поля, в которых можно изменить имя и фамилию.

Image08

Кнопка Удалить также работает. Нажмите кнопку Удалить для строки с датой регистрации, и строка исчезнет. (Строки без даты регистрации представляют преподавателей, и вы можете получить ошибку целостности данных. В следующем руководстве вы отфильтруете этот список, чтобы включить только учащихся.)

Отображение данных из свойства навигации

Теперь предположим, что вы хотите узнать, сколько курсов регистрируется каждый учащийся. Entity Framework предоставляет эти сведения в свойстве навигации StudentGrades сущности Person . Так как структура базы данных не позволяет зарегистрироваться учащегося в курсе без присвоения оценки, в этом руководстве можно предположить, что наличие строки в StudentGrade строке таблицы, связанной с курсом, совпадает с тем, что и зачисление в курс. (Свойство Courses навигации предназначено только для преподавателей.)

При использовании атрибута ContextTypeNameEntityDataSource элемента управления Entity Framework автоматически получает сведения для свойства навигации при доступе к его свойству. Это называется отложенной загрузкой. Однако это может быть неэффективным, так как это приводит к отдельному вызову базы данных каждый раз, когда требуются дополнительные сведения. Если требуются данные из свойства навигации для каждой сущности, возвращаемой элементом EntityDataSource управления, эффективнее получить связанные данные вместе с самой сущностью в одном вызове базы данных. Это называется неотложной загрузкой, и вы указываете неотложную загрузку для свойства навигации, задав Include свойство EntityDataSource элемента управления .

В Students.aspx нужно показать количество курсов для каждого учащегося, поэтому лучше всего выбрать загрузку. Если вы отображали всех учащихся, но отображали количество курсов только для некоторых из них (что потребовало бы написания кода в дополнение к разметке), отложенная загрузка может быть лучшим выбором.

Откройте students.aspx или перейдите в него, перейдите в режим конструктора , выберите StudentsEntityDataSourceи в окне Свойства задайте для свойства Include значение StudentGrades. (Если вы хотите получить несколько свойств навигации, можно указать их имена, разделенные запятыми, например StudentGrades, Courses.)

Изображение19

Переключитесь в представление источника . В элементе 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 управления, который позволит добавлять новых учащихся. Закройте браузер и создайте новую веб-страницу с помощью страницы master 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>

Эта разметка создает элемент EntityDataSource управления, аналогичный созданному в Students.aspx, за исключением включения вставки. Как и в случае с элементом GridView управления, связанные поля DetailsView элемента управления кодируются точно так же, как и для элемента управления данными, который напрямую подключается к базе данных, за исключением того, что они ссылаются на свойства сущности. В этом случае DetailsView элемент управления используется только для вставки строк, поэтому для режима по умолчанию задано значение Insert.

Запустите страницу и добавьте нового учащегося.

Снимок экрана: окно интернет-Обозреватель с представлением

После вставки нового учащегося ничего не произойдет, но если запустить Students.aspx, вы увидите новые сведения об учащемся.

Отображение данных в списке Drop-Down

На следующих шагах вы привязите элемент управления к набору DropDownList сущностей с помощью EntityDataSource элемента управления . В этой части учебника вы не будете много делать с этим списком. В последующих частях, однако, вы будете использовать список, чтобы позволить пользователям выбирать отдел для отображения курсов, связанных с отделом.

Создайте веб-страницу с именем Courses.aspx. В представлении источника добавьте заголовок в Content элемент управления с именем Content2:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Courses by Department</h2>
</asp:Content>

В режиме конструктора добавьте элемент EntityDataSource управления на страницу, как и раньше, за исключением того, что на этот раз назовите его DepartmentsEntityDataSource. Выберите Отделы в качестве значения EntitySetName и выберите только свойства DepartmentID и Name .

Изображение15

На вкладке Стандартныйпанели элементов перетащите DropDownList элемент управления на страницу, назовите его DepartmentsDropDownList, щелкните смарт-тег и выберите Выбрать источник данных , чтобы запустить мастер настройки источника данных.

Изображение16

На шаге Выбор источника данных выберите DepartmentsEntityDataSource в качестве источника данных, щелкните Обновить схему, а затем выберите Имя в качестве отображаемого поля данных и DepartmentID в качестве поля данных значения. Нажмите кнопку ОК.

Изображение17

Метод, используемый для привязки данных элемента управления с помощью 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 элементом управления, также может отличаться от других элементов управления источником данных при фильтрации, группировке и заказе данных.