Начало работы с Entity Framework 4.0 Database First и ASP.NET 4 Веб-формы — Часть 7

Том Дайкстра

Пример веб-приложения Contoso University демонстрирует создание приложений веб-форм ASP.NET с помощью Entity Framework 4.0 и Visual Studio 2010. Сведения о серии учебников см. в первом руководстве в серии

Использование хранимых процедур

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

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

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

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

В этом руководстве вы создадите хранимые процедуры в базе данных для вставки Student и Instructor сущностей. Вы добавите их в модель данных и укажите, что Entity Framework должна использовать их для добавления Student и Instructor сущностей в базу данных. Вы также создадите хранимую процедуру, которую можно использовать для извлечения Course сущностей.

Создание хранимых процедур в базе данных

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

В обозревателе серверов разверните School.mdf, щелкните правой кнопкой мыши хранимые процедуры и выберите "Добавить новую хранимую процедуру".

image15

Скопируйте следующие инструкции SQL и вставьте их в окно хранимой процедуры, заменив скелет хранимой процедуры.

CREATE PROCEDURE [dbo].[InsertStudent]
    @LastName nvarchar(50),
    @FirstName nvarchar(50),
    @EnrollmentDate datetime
    AS
    INSERT INTO dbo.Person (LastName, 
                FirstName, 
                EnrollmentDate)
    VALUES (@LastName, 
        @FirstName, 
        @EnrollmentDate);
    SELECT SCOPE_IDENTITY() as NewPersonID;

image14

Student сущности имеют четыре свойства: PersonID, LastName, FirstNameи EnrollmentDate. База данных автоматически создает значение идентификатора, а хранимая процедура принимает параметры для остальных трех. Хранимая процедура возвращает значение ключа записи новой строки, чтобы Entity Framework мог отслеживать его в версии сущности, которая хранится в памяти.

Сохраните и закройте окно хранимой процедуры.

Создайте хранимую InsertInstructor процедуру таким же образом, используя следующие инструкции SQL:

CREATE PROCEDURE [dbo].[InsertInstructor]
        @LastName nvarchar(50),
    @FirstName nvarchar(50),
    @HireDate datetime
    AS
    INSERT INTO dbo.Person (LastName, 
                FirstName, 
                HireDate)
    VALUES (@LastName, 
        @FirstName, 
        @HireDate);
    SELECT SCOPE_IDENTITY() as NewPersonID;

Создайте Update хранимые процедуры для Student и Instructor сущностей. (База данных уже имеет хранимую DeletePerson процедуру, которая будет работать как для Instructor, так и для Student сущностей.)

CREATE PROCEDURE [dbo].[UpdateStudent]
    @PersonID int,
    @LastName nvarchar(50),
    @FirstName nvarchar(50),
    @EnrollmentDate datetime
    AS
    UPDATE Person SET LastName=@LastName, 
            FirstName=@FirstName,
            EnrollmentDate=@EnrollmentDate
    WHERE PersonID=@PersonID;
CREATE PROCEDURE [dbo].[UpdateInstructor]
    @PersonID int,
    @LastName nvarchar(50),
    @FirstName nvarchar(50),
    @HireDate datetime
    AS
    UPDATE Person SET LastName=@LastName, 
            FirstName=@FirstName,
            HireDate=@HireDate
    WHERE PersonID=@PersonID;

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

Чтобы создать хранимую процедуру, которая считывает, а не обновляет данные, создайте ее, которая выбирает все Course сущности, используя следующие инструкции SQL:

CREATE PROCEDURE [dbo].[GetCourses]
            AS
            SELECT CourseID, Title, Credits, DepartmentID FROM dbo.Course

Добавление хранимых процедур в модель данных

Хранимые процедуры теперь определены в базе данных, но их необходимо добавить в модель данных, чтобы сделать их доступными в Entity Framework. Откройте SchoolModel.edmx, щелкните правой кнопкой мыши область конструктора и выберите "Обновить модель" из базы данных. На вкладке Добавить диалогового окна Выбор объектов базы данных разверните узел Хранимые процедуры, выберите только что созданные хранимые процедуры и хранимую процедуру DeletePerson, а затем нажмите кнопку Готово.

image20

Сопоставление хранимых процедур

В конструкторе моделей данных щелкните правой кнопкой мыши Student сущность и выберите сопоставление хранимых процедур.

image21

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

image22

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

image23

В том же окне сведений о сопоставлении сопоставьте Update функцию с UpdateStudent хранимой процедурой (убедитесь, что вы указали FirstMidName значение параметра для FirstNameInsert хранимой процедуры, как и для хранимой процедуры) и Delete функцию с хранимой процедуройDeletePerson.

image01

Выполните ту же процедуру, чтобы сопоставить хранимые процедуры вставки, обновления и удаления для инструкторов с сущностью Instructor.

image02

Для хранимых процедур, которые считывают, а не обновляют данные, используйте окно браузера моделей для сопоставления хранимой процедуры с типом сущности, возвращаемой им. В конструкторе моделей данных щелкните правой кнопкой мыши область конструктора и выберите "Браузер моделей". Откройте узел SchoolModel.Store и откройте узел хранимых процедур . Затем щелкните правой GetCourses кнопкой мыши хранимую процедуру и выберите команду "Добавить импорт функции".

image24

В диалоговом окне "Добавить импорт функции" в разделе "Возвращает коллекцию из" выберите "Сущности", а затем выберите Course в качестве возвращаемого типа сущности. По завершении нажмите кнопку "ОК". Сохраните и закройте edmx-файл .

image25

Использование хранимых процедур вставки, обновления и удаления

Хранимые процедуры для вставки, обновления и удаления данных автоматически используются Entity Framework после их добавления в модель данных и сопоставлении их с соответствующими сущностями. Теперь вы можете запустить страницу StudentsAdd.aspx, и каждый раз при создании нового учащегося Entity Framework будет использовать InsertStudent хранимую процедуру для добавления новой строки в таблицу Student.

image03

Запустите страницу Students.aspx , а новый учащийся появится в списке.

image04

Измените имя, чтобы убедиться, что функция обновления работает, а затем удалите учащегося, чтобы убедиться, что функция удаления работает.

image05

Использование выбора хранимых процедур

Entity Framework не запускает хранимые процедуры автоматически, например GetCourses, и их нельзя использовать с элементом EntityDataSource управления. Чтобы использовать их, вы вызываете их из кода.

Откройте файл InstructorsCourses.aspx.cs . Метод PopulateDropDownLists использует запрос LINQ-to-Entities для получения всех сущностей курса, чтобы он смог провести цикл по списку и определить, к каким из них назначен инструктор, и какие из них не назначены:

var allCourses = (from c in context.Courses
                  select c).ToList();

Замените его следующим кодом:

var allCourses = context.GetCourses();

Страница теперь использует хранимую процедуру GetCourses для получения списка всех курсов. Запустите страницу, чтобы убедиться, что она работает, как и раньше.

(Свойства навигации сущностей, полученных хранимой процедурой, могут не заполняться автоматически данными, связанными с этими сущностями, в зависимости от ObjectContext параметров по умолчанию. Дополнительные сведения см. в разделе "Загрузка связанных объектов " в библиотеке MSDN.)

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