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


Новые возможности .NET Framework 4.0

Том Дайкстра (Tom Dykstra)

Эта серия руководств основана на веб-приложении Университета Contoso, созданном с помощью начало работы с серией руководств по Entity Framework. Если вы не выполнили предыдущие руководства, в качестве отправной точки для этого руководства вы можете скачать созданное приложение . Вы также можете скачать приложение , созданное в полной серии руководств. Если у вас есть вопросы по этим руководствам, вы можете опубликовать их на форуме ASP.NET Entity Framework.

В предыдущем руководстве вы рассмотрели некоторые методы повышения производительности веб-приложения, использующего Entity Framework. В этом руководстве рассматриваются некоторые из наиболее важных новых функций в версии 4 Entity Framework, а также ссылки на ресурсы, предоставляющие более полное представление обо всех новых возможностях. В этом руководстве выделены следующие функции:

  • Связи с внешним ключом.
  • Выполнение определяемых пользователем команд SQL.
  • Разработка на основе модели.
  • Поддержка POCO.

Кроме того, в этом руководстве кратко описывается разработка с использованием кода, которая появится в следующем выпуске Entity Framework.

Чтобы приступить к работе с этим руководством, запустите Visual Studio и откройте веб-приложение Университета Contoso, с которым вы работали в предыдущем руководстве.

ассоциации Foreign-Key

Версия 3.5 Entity Framework включала свойства навигации, но не включала свойства внешнего ключа в модель данных. Например, столбцы CourseIDStudentGrade и StudentID таблицы будут опущены в сущностиStudentGrade.

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

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

В качестве примера того, как внешние ключи в модели данных могут упростить код, рассмотрим, как вам пришлось бы кодировать страницу DepartmentsAdd.aspx без них. В сущности Department свойство является внешним ключом, Administrator соответствующим PersonID в сущности Person . Чтобы установить связь между новым отделом и его администратором, вам нужно было задать значение свойства Administrator в обработчике ItemInserting событий элемента управления для исходящего трафика данных:

protected void DepartmentsDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
    e.Values["Administrator"] = administratorsDropDownList.SelectedValue;
}

Без внешних ключей в модели данных вы обработаете Inserting событие элемента управления источником данных, а не ItemInserting событие элемента управления для исходящего трафика данных, чтобы получить ссылку на саму сущность перед добавлением сущности в набор сущностей. При наличии этой ссылки вы устанавливаете связь с помощью кода, как в следующих примерах:

departmentEntityToBeInserted.PersonReference.EntityKey = new System.Data.EntityKey("SchoolEntities.Departments", "PersonID", Convert.ToInt32(administratorsDropDownList.SelectedValue));
departmentEntityToBeInserted.Person = context.People.Single(p => p.PersonID == Convert.ToInt32(administratorsDropDownList.SelectedValue));

Как видно из записи блога команды Entity Framework о связях с внешними ключами, существуют и другие случаи, когда разница в сложности кода гораздо больше. Для удовлетворения потребностей тех, кто предпочитает жить с подробными сведениями о реализации в концептуальной модели данных для упрощения кода, Entity Framework теперь предоставляет возможность включения внешних ключей в модель данных.

В терминологии Entity Framework, если вы включаете внешние ключи в модель данных, вы используете связи с внешними ключами, а при исключении внешних ключей используются независимые связи.

Выполнение User-Defined команд SQL

В более ранних версиях Entity Framework не было простого способа создания собственных команд SQL на лету и их выполнения. Либо платформа Entity Framework динамически создавала команды SQL, либо вам пришлось создать хранимую процедуру и импортировать ее как функцию. Версия 4 добавляет ExecuteStoreQuery методы ObjectContext и ExecuteStoreCommand класса , которые упрощают передачу любого запроса непосредственно в базу данных.

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

Создайте новую страницу, которая использует страницу master Site.Master, и назовите ее UpdateCredits.aspx. Затем добавьте следующую разметку в элемент управления с Content именем Content2:

<h2>Update Credits</h2>
    Enter the number to multiply the current number of credits by: 
    <asp:TextBox ID="CreditsMultiplierTextBox" runat="server"></asp:TextBox>
    <br /><br />
    <asp:Button ID="ExecuteButton" runat="server" Text="Execute" OnClick="ExecuteButton_Click" /><br /><br />
    Rows affected:
    <asp:Label ID="RowsAffectedLabel" runat="server" Text="0" ViewStateMode="Disabled"></asp:Label><br /><br />

Эта разметка создает TextBox элемент управления, в котором пользователь может ввести значение множителя, Button элемент управления для щелчка для выполнения команды и Label элемент управления для указания количества затронутых строк.

Откройте Файл UpdateCredits.aspx.cs и добавьте следующую using инструкцию и обработчик для события кнопки Click :

using ContosoUniversity.DAL;
protected void ExecuteButton_Click(object sender, EventArgs e)
{
    using (SchoolEntities context = new SchoolEntities())
    {
        RowsAffectedLabel.Text = context.ExecuteStoreCommand("UPDATE Course SET Credits = Credits * {0}", CreditsMultiplierTextBox.Text).ToString();
    }
}

Этот код выполняет команду SQL Update , используя значение в текстовом поле, и использует метку для отображения количества затронутых строк. Перед запуском страницы запустите страницу Courses.aspx , чтобы получить изображение "до" некоторых данных.

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

Запустите UpdateCredits.aspx, введите "10" в качестве множителя и нажмите кнопку Выполнить.

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

Запустите страницу Courses.aspx еще раз, чтобы просмотреть измененные данные.

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

(Если вы хотите вернуть число кредитов в исходное значение, в файле UpdateCredits.aspx.cs измените Credits * {0} на Credits / {0} и повторно запустите страницу, введя 10 в качестве делителя.)

Дополнительные сведения о выполнении запросов, определяемых в коде, см. в разделе Практическое руководство. Непосредственное выполнение команд в источнике данных.

Разработка Model-First

В этих пошаговых руководствах вы сначала создали базу данных, а затем создали модель данных на основе структуры базы данных. В Entity Framework 4 можно начать с модели данных и создать базу данных на основе структуры модели данных. Если вы создаете приложение, для которого база данных еще не существует, подход model-first позволяет создавать сущности и связи, которые имеют смысл для приложения, не беспокоясь о физической реализации. (Однако это остается верным только на начальных этапах развития. В конечном итоге база данных будет создана и в ней будут рабочие данные, и воссоздание ее из модели больше не будет практичным; На этом этапе вы вернетесь к подходу на основе базы данных.)

В этом разделе руководства вы создадите простую модель данных и создадите на ее основе базу данных.

В Обозреватель решений щелкните правой кнопкой мыши папку DAL и выберите Добавить новый элемент. В диалоговом окне Добавление нового элемента в разделе Установленные шаблоны выберите Данные , а затем выберите шаблон модель ADO.NET entity Data Model . Назовите новый файл AlumniAssociationModel.edmx и нажмите кнопку Добавить.

Image06

При этом запустится мастер модели entityяныхх. . На шаге Выбор содержимого модели выберите Пустая модель и нажмите кнопку Готово.

Image07

Откроется Designer Entity Data Model с пустой областью конструктора. Перетащите элемент Entity с панели элементов в область конструктора.

Image08

Измените имя сущности с Entity1 на Alumnus, измените Id имя свойства на AlumnusIdи добавьте новое скалярное свойство с именем Name. Чтобы добавить новые свойства, нажмите клавишу ВВОД после изменения имени столбца или щелкните правой Id кнопкой мыши сущность и выберите Добавить скалярное свойство. Тип по умолчанию для новых свойств — String, что подходит для этой простой демонстрации, но, конечно, вы можете изменить такие параметры, как тип данных, в окне Свойства .

Создайте другую сущность таким же образом и назовите ее Donation. Измените свойство на IdDonationId и добавьте скалярное свойство с именем DateAndAmount.

Image09

Чтобы добавить связь между этими двумя сущностями, щелкните ее правой Alumnus кнопкой мыши, выберите Добавить, а затем — Связь.

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

Значения по умолчанию в диалоговом окне Добавление связи являются нужными (один ко многим, включить свойства навигации, включить внешние ключи), поэтому просто нажмите кнопку ОК.

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

Конструктор добавляет строку связи и свойство внешнего ключа.

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

Теперь все готово к созданию базы данных. Щелкните правой кнопкой мыши область конструктора и выберите Создать базу данных из модели.

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

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

На шаге Choose Your Data Connection (Выбор подключения к данным ) щелкните New Connection (Создать подключение).

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

В диалоговом окне Свойства подключения выберите локальный экземпляр SQL Server Express и назовите базу данных AlumniAssociation.

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

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

На шаге Сводка и Параметры нажмите кнопку Готово.

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

Создается SQL-файл с командами языка определения данных (DDL), но команды еще не выполнены.

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

Используйте такое средство, как SQL Server Management Studio, чтобы запустить скрипт и создать таблицы, как это можно было сделать при создании School базы данных для первого руководства из серии учебников по начало работы. (Если вы не скачали базу данных.)

Теперь модель данных можно использовать на AlumniAssociation веб-страницах так же, как School и модель. Чтобы попробовать это, добавьте некоторые данные в таблицы и создайте веб-страницу, на котором отображаются данные.

С помощью server Обозреватель добавьте следующие строки в Alumnus таблицы и Donation .

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

Создайте новую веб-страницу с именем Alumni.aspx, которая использует страницу master Site.Master. Добавьте следующую разметку в элемент управления с Content именем Content2:

<h2>Alumni</h2>
    <asp:EntityDataSource ID="AlumniEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.AlumniAssociationModelContainer" EnableFlattening="False" 
        EntitySetName="Alumni">
    </asp:EntityDataSource>
    <asp:GridView ID="AlumniGridView" runat="server" 
        DataSourceID="AlumniEntityDataSource" AutoGenerateColumns="False"
        OnRowDataBound="AlumniGridView_RowDataBound"
        DataKeyNames="AlumnusId">
        <Columns>
            <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
            <asp:TemplateField HeaderText="Donations">
                <ItemTemplate>
                    <asp:GridView ID="DonationsGridView" runat="server" AutoGenerateColumns="False">
                        <Columns>
                            <asp:BoundField DataField="DateAndAmount" HeaderText="Date and Amount" />
                        </Columns>
                    </asp:GridView>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Эта разметка создает вложенные GridView элементы управления, внешние для отображения имен выпускников и внутренние для отображения дат и сумм пожертвований.

Откройте файл Alumni.aspx.cs. using Добавьте оператор для уровня доступа к данным и обработчик для события внешнего GridView элемента управленияRowDataBound:

using ContosoUniversity.DAL; 

// ...

protected void AlumniGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var alumnus = e.Row.DataItem as Alumnus;
        var donationsGridView = (GridView)e.Row.FindControl("DonationsGridView");
        donationsGridView.DataSource = alumnus.Donations.ToList();
        donationsGridView.DataBind();
    }
}

Этот код привязывает внутренний GridView элемент управления с помощью Donations свойства навигации сущности текущей Alumnus строки.

Запустите страницу.

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

(Примечание. Эта страница включена в загружаемый проект, но для его работы необходимо создать базу данных в локальном экземпляре SQL Server Express; база данных не включается в виде MDF-файла в папку App_Data.)

Дополнительные сведения об использовании функции model-first в Entity Framework см. в разделе Model-First в Entity Framework 4.

Поддержка POCO

При использовании методологии проектирования на основе предметной области вы разрабатываете классы данных, представляющие данные и поведение, относящиеся к бизнес-предметной области. Эти классы должны быть независимыми от какой-либо конкретной технологии, используемой для хранения (сохранения) данных; иными словами, они должны быть невежественными. Незнание сохраняемости также может упростить модульный тест класса, так как проект модульного теста может использовать любую технологию сохраняемости, наиболее удобную для тестирования. Более ранние версии Entity Framework предлагали ограниченную поддержку незнаний сохраняемости, так как классы сущностей должны были наследовать от EntityObject класса и, таким образом, включали большую часть функциональных возможностей, характерных для Entity Framework.

Платформа Entity Framework 4 предоставляет возможность использовать классы сущностей, которые не наследуются от EntityObject класса и поэтому не учитывают сохраняемость. В контексте Entity Framework такие классы обычно называются обычными объектами CLR ( POCO или POCOs). Вы можете создавать классы POCO вручную или автоматически создавать их на основе существующей модели данных с помощью шаблонов преобразования текстовых шаблонов (T4), предоставляемых Entity Framework.

Дополнительные сведения об использовании POCOs в Entity Framework см. в следующих ресурсах:

Разработка Code-First

Для поддержки POCO в Entity Framework 4 по-прежнему требуется создать модель данных и связать классы сущностей с моделью данных. В следующем выпуске Entity Framework будет включена функция разработки кода. Эта функция позволяет использовать Entity Framework с собственными классами POCO без использования конструктора моделей данных или XML-файла модели данных. (Поэтому этот параметр также называется только для кода; Как code-first , так и code-only относятся к одной и той же функции Entity Framework.)

Дополнительные сведения об использовании подхода code-first к разработке см. в следующих ресурсах:

Кроме того, новое руководство по Code-First MVC, которое создает приложение, аналогичное приложению Университета Contoso, будет опубликовано весной 2011 года по адресу https://asp.net/entity-framework/tutorials

Дополнительные сведения

На этом вы узнаете о новых возможностях Entity Framework и в этой серии учебников Продолжение работы с Entity Framework. Дополнительные сведения о новых функциях в Entity Framework 4, которые не рассматриваются здесь, см. в следующих ресурсах: