Создание классов модели в Entity Framework (VB)

от Майкрософт

В этом руководстве описано, как использовать ASP.NET MVC с Microsoft Entity Framework. Вы узнаете, как использовать мастер сущностей для создания модели ADO.NET entity Data Model. В ходе работы с этим руководством мы создадим веб-приложение, демонстрирующее выбор, вставку, обновление и удаление данных базы данных с помощью Entity Framework.

Цель этого руководства — объяснить, как можно создавать классы доступа к данным с помощью Microsoft Entity Framework при создании приложения ASP.NET MVC. В этом руководстве предполагается, что предыдущие знания о Microsoft Entity Framework отсутствуют. В конце этого руководства вы узнаете, как использовать Entity Framework для выбора, вставки, обновления и удаления записей базы данных.

Microsoft Entity Framework — это средство объектно-реляционного сопоставления (O/RM), которое позволяет автоматически создавать уровень доступа к данным из базы данных. Entity Framework позволяет избежать трудоемкой работы по созданию классов доступа к данным вручную.

Примечание

Между ASP.NET MVC и Microsoft Entity Framework нет существенного соединения. Существует несколько альтернатив Entity Framework, которые можно использовать с ASP.NET MVC. Например, вы можете создавать классы модели MVC с помощью других средств O/RM, таких как Microsoft LINQ to SQL, NHibernate или SubSonic.

Чтобы продемонстрировать, как можно использовать Microsoft Entity Framework с ASP.NET MVC, мы создадим простой пример приложения. Мы создадим приложение Базы данных фильмов, которое позволяет отображать и редактировать записи базы данных фильмов.

В этом руководстве предполагается, что у вас есть Visual Studio 2008 или Visual Web Developer 2008 с пакетом обновления 1 (SP1). Для использования Entity Framework требуется пакет обновления 1 ( SP1). Вы можете скачать Visual Studio 2008 с пакетом обновления 1 (SP1) или Visual Web Developer с пакетом обновления 1 (SP1) по следующему адресу:

https://www.asp.net/downloads/

Создание примера базы данных movie

Приложение Movie Database использует таблицу базы данных с именем Movies, содержащую следующие столбцы:

Имя столбца Тип данных Разрешить значения NULL? Первичный ключ?
Идентификатор INT False True
Заголовок nvarchar(100) Неверно Неверно
Директор nvarchar(100) Неверно Неверно

Эту таблицу можно добавить в проект ASP.NET MVC, выполнив следующие действия.

  1. Щелкните правой кнопкой мыши папку App_Data в окне Обозреватель решений и выберите пункт меню Добавить, Новый элемент.
  2. В диалоговом окне Добавление нового элемента выберите SQL Server База данных, присвойте базе данных имя MoviesDB.mdf и нажмите кнопку Добавить.
  3. Дважды щелкните файл MoviesDB.mdf, чтобы открыть окно Обозреватель сервера или база данных Обозреватель.
  4. Разверните подключение к базе данных MoviesDB.mdf, щелкните правой кнопкой мыши папку Таблицы и выберите пункт меню Добавить новую таблицу.
  5. В Designer таблицы добавьте столбцы Id, Title и Director.
  6. Нажмите кнопку Сохранить (значок дискеты), чтобы сохранить новую таблицу с именем Фильмы.

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

Создание модели данных сущностей ADO.NET

Чтобы использовать Entity Framework, необходимо создать модель данных сущности. Вы можете воспользоваться преимуществами мастера моделей entity data в Visual Studio для автоматического создания модели entity data из базы данных.

Выполните следующие действия.

  1. Щелкните правой кнопкой мыши папку Models в окне Обозреватель решений и выберите пункт меню Добавить, Новый элемент.
  2. В диалоговом окне Добавление нового элемента выберите категорию Данные (см. рис. 1).
  3. Выберите шаблон ADO.NET Entity Data Model , присвойте ей имя MoviesDBModel.edmx и нажмите кнопку Добавить . При нажатии кнопки Добавить запустится мастер модели данных.
  4. На шаге Выбор содержимого модели выберите параметр Создать из базы данных и нажмите кнопку Далее (см. рис. 2).
  5. На шаге Выбор подключения к данным выберите подключение к базе данных MoviesDB.mdf, введите имя параметров подключения сущностей MoviesDBEntities и нажмите кнопку Далее (см. рис. 3).
  6. На шаге Выбор объектов базы данных выберите таблицу базы данных Movie и нажмите кнопку Готово (см. рис. 4).

После выполнения этих действий откроется Designer ADO.NET Entity Data Model (Entity Designer).

Рис. 1. Создание новой модели данных сущности

clip_image002

Рис. 2. Выбор этапа содержимого модели

clip_image004

Рис. 3. Выбор подключения к данным

clip_image006

Рис. 4. Выбор объектов базы данных

clip_image008

Изменение модели данных сущностей ADO.NET

После создания модели данных сущности можно изменить модель, воспользовавшись Designer сущностей (см. рис. 5). Вы можете в любое время открыть Designer сущностей, дважды щелкнув файл MoviesDBModel.edmx в папке Models в окне Обозреватель решений.

Рис. 5. Designer модель данных сущностей ADO.NET

clip_image010

Например, можно использовать Designer сущностей для изменения имен классов, создаваемых мастером данных модели сущностей. Мастер создал новый класс доступа к данным с именем Movies. Другими словами, мастер присвоил классу то же имя, что и таблица базы данных. Так как мы будем использовать этот класс для представления конкретного экземпляра Movie, следует переименовать класс с Movies на Movie.

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

Рис. 6. Изменение имени сущности

clip_image012

Не забудьте сохранить модель entity Data Model после внесения изменений, нажав кнопку Сохранить (значок дискеты). В фоновом режиме Designer сущностей создает набор классов Visual Basic .NET. Эти классы можно просмотреть, открыв MoviesDBModel. файл Designer.vb из окна Обозреватель решений.

Не изменяйте код в файле Designer.vb, так как изменения будут перезаписаны при следующем использовании Designer сущностей. Если вы хотите расширить функциональные возможности классов сущностей, определенных в файле Designer.vb, можно создать разделяемые классы в отдельных файлах.

Выбор записей базы данных с помощью Entity Framework

Давайте приступим к созданию приложения базы данных фильмов, создав страницу со списком записей фильмов. Контроллер Home в листинге 1 предоставляет действие с именем Index(). Действие Index() возвращает все записи фильмов из таблицы базы данных Movie, используя entity Framework.

Листинг 1. Controllers\HomeController.vb

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Private _db As MoviesDBEntities

    Public Sub New()
        _db = New MoviesDBEntities()
    End Sub

    Public Function Index()
        ViewData.Model = _db.MovieSet.ToList()
        Return View()
    End Function

End Class

Обратите внимание, что контроллер в листинге 1 содержит конструктор. Конструктор инициализирует поле уровня класса с именем _db. Поле _db представляет сущности базы данных, созданные Платформой Microsoft Entity Framework. Поле _db является экземпляром класса MoviesDBEntities, созданного Designer Сущности.

Поле _db используется в действии Index() для получения записей из таблицы базы данных Movies. Выражение _db. MovieSet представляет все записи из таблицы базы данных Movies. Метод ToList() используется для преобразования набора фильмов в универсальную коллекцию объектов Movie: List( Of Movie).

Записи фильмов извлекаются с помощью LINQ to Entities. Действие Index() в листинге 1 использует синтаксис метода LINQ для получения набора записей базы данных. При желании можно использовать синтаксис запросов LINQ. Следующие два оператора выполняют то же самое:

ViewData.Model = _db.MovieSet.ToList()
ViewData.Model = (from m in _db.MovieSet select m).ToList()

Используйте любой синтаксис LINQ (синтаксис методов или синтаксис запросов), который вы найдете наиболее интуитивно понятным. Между этими двумя подходами нет никакой разницы в производительности. Разница заключается только в стиле.

Представление в листинге 2 используется для отображения записей фильмов.

Листинг 2. Views\Home\Index.aspx

<%@ Page Language="VB" 
  Inherits="System.Web.Mvc.ViewPage(Of List(Of MvcApplication1.Movie))" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Index</title>
</head>
<body>
    <div>
    
<%  For Each m In Model%>

    Title: <%= m.Title %>
    <br />
    Director: <%= m.Director %>
    <br />
    <%=Html.ActionLink("Edit", "Edit", New With {.id = m.Id})%>
    <%=Html.ActionLink("Delete", "Delete", New With {.id = m.Id})%>
       
        <hr />
<% Next%>
    
    <%= Html.ActionLink("Add Movie", "Add") %>
    
    </div>
</body>
</html>

Представление в листинге 2 содержит цикл For Each , который выполняет итерацию по каждой записи фильма и отображает значения свойств Title и Director записи фильма. Обратите внимание, что рядом с каждой записью отображается ссылка Изменить и удалить. Кроме того, в нижней части представления появится ссылка Добавить фильм (см. рис. 7).

Рис. 7. Представление индекса

clip_image014

Представление индекса — это типизированное представление. Представление индекса имеет директиву <%@ Page %> , которая включает атрибут Inherits. Атрибут Inherits приводит свойство ViewData.Model к строго типизированной универсальной коллекции List объектов Movie — List(Of Movie).

Вставка записей базы данных с помощью Entity Framework

Платформа Entity Framework позволяет легко вставлять новые записи в таблицу базы данных. В листинге 3 содержатся два новых действия, добавленных в класс контроллера Home, которые можно использовать для вставки новых записей в таблицу базы данных Movie.

Листинг 3. Controllers\HomeController.vb (добавление методов)

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Public Function Add()
        Return View()
    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function Add(ByVal form As FormCollection)
        Dim movieToAdd As New Movie()

        ' Deserialize (Include white list!)
        TryUpdateModel(movieToAdd, New String() {"Title", "Director"}, form.ToValueProvider())

        ' Validate
        If String.IsNullOrEmpty(movieToAdd.Title) Then
            ModelState.AddModelError("Title", "Title is required!")
        End If
        If String.IsNullOrEmpty(movieToAdd.Director) Then
            ModelState.AddModelError("Director", "Director is required!")
        End If

        ' If valid, save movie to database
        If (ModelState.IsValid) Then
            _db.AddToMovieSet(movieToAdd)
            _db.SaveChanges()
            Return RedirectToAction("Index")
        End If

        ' Otherwise, reshow form
        Return View(movieToAdd)
    End Function

End Class

Первое действие Add() просто возвращает представление. Представление содержит форму для добавления новой записи базы данных фильмов (см. рис. 8). При отправке формы вызывается второе действие Add().

Обратите внимание, что второе действие Add() украшено атрибутом AcceptVerbs. Это действие можно вызвать только при выполнении операции HTTP POST. Другими словами, это действие можно вызвать только при публикации HTML-формы.

Второе действие Add() создает новый экземпляр класса Entity Framework Movie с помощью метода TryUpdateModel() ASP.NET MVC. Метод TryUpdateModel() принимает поля в FormCollection, переданном методу Add(), и присваивает значения этих полей формы HTML классу Movie.

При использовании Entity Framework необходимо предоставить "список безопасных" свойств при использовании методов TryUpdateModel или UpdateModel для обновления свойств класса сущности.

Затем действие Add() выполняет простую проверку формы. Действие проверяет, имеют ли свойства Title и Director значения. При возникновении ошибки проверки в ModelState добавляется сообщение об ошибке проверки.

Если ошибок проверки нет, новая запись фильма добавляется в таблицу базы данных Movies с помощью Entity Framework. Новая запись добавляется в базу данных со следующими двумя строками кода:

_db.AddToMovieSet(movieToAdd)
_db.SaveChanges()

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

Рис. 8. Представление "Добавить"

clip_image016

Обновление записей базы данных с помощью Entity Framework

При редактировании записи базы данных с помощью Entity Framework можно следовать практически тому же подходу, который мы только что следовали для вставки новой записи базы данных. В листинге 4 содержатся два новых действия контроллера с именем Edit(). Первое действие Edit() возвращает HTML-форму для редактирования записи фильма. Второе действие Edit() пытается обновить базу данных.

Листинг 4. Controllers\HomeController.vb (edit methods)

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Public Function Edit(ByVal id As Integer)
        ' Get movie to update
        Dim movieToUpdate As Movie = _db.MovieSet.First(Function(m) m.Id = id)
        ViewData.Model = movieToUpdate
        Return View()
    End Function

    <AcceptVerbs(HttpVerbs.Post)> _
    Public Function Edit(ByVal form As FormCollection)

        ' Get movie to update
        Dim id As Integer = Integer.Parse(form("id"))
        Dim movieToUpdate As Movie = _db.MovieSet.First(Function(m) m.Id = id)

        ' Deserialize (Include white list!)
        TryUpdateModel(movieToUpdate, New String() {"Title", "Director"}, form.ToValueProvider)

        ' Validate
        If String.IsNullOrEmpty(movieToUpdate.Title) Then
            ModelState.AddModelError("Title", "Title is required!")
        End If
        If String.IsNullOrEmpty(movieToUpdate.Director) Then
            ModelState.AddModelError("Director", "Director is required!")
        End If

        ' If valid, save movie to database
        If (ModelState.IsValid) Then
            _db.SaveChanges()
            Return RedirectToAction("Index")
        End If

        ' Otherwise, reshow form
        Return View(movieToUpdate)
    End Function

End Class

Второе действие Edit() начинается с получения записи фильма из базы данных, которая соответствует идентификатору редактируемого фильма. Следующая инструкция LINQ to Entities захватывает первую запись базы данных, соответствующую определенному идентификатору:

Dim movieToUpdate As Movie = _db.MovieSet.First(Function(m) m.Id = id)

Затем метод TryUpdateModel() используется для назначения значений полей HTML-формы свойствам сущности movie. Обратите внимание, что предоставляется список надежных данных, указывающий точные свойства для обновления.

Затем выполняется простая проверка, чтобы убедиться, что свойства Movie Title и Director имеют значения. Если ни одно из свойств не имеет значения, в ModelState добавляется сообщение об ошибке проверки, а ModelState.IsValid возвращает значение false.

Наконец, если ошибок проверки нет, то базовая таблица базы данных Movies обновляется с учетом любых изменений путем вызова метода SaveChanges().

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

Листинг 5. Views\Home\Edit.aspx

<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage(Of MvcApplication1.Movie)" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Edit</title>
    <style type="text/css">
    
    .input-validation-error
    {
        background-color:Yellow;
    }
    
    </style>    
</head>
<body>
    <div>

<h1>Edit Movie</h1>

<form method="post" action="/Home/Edit">

    <!-- Include Hidden Id -->
    <%= Html.Hidden("id") %>

    Title:
    <br />
    <%= Html.TextBox("title") %>
    
    <br /><br />
    Director:
    <br />
    <%= Html.TextBox("director") %>
    
    <br /><br />
    <input type="submit" value="Edit Movie" />
</form>
    
    </div>
</body>
</html>

Удаление записей базы данных с помощью Entity Framework

Последняя операция базы данных, которую необходимо решить в этом руководстве, — удаление записей базы данных. Для удаления определенной записи базы данных можно использовать действие контроллера, описанное в листинге 6.

Листинг 6 — \Controllers\HomeController.vb (действие удаления)

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Public Function Delete(ByVal id As Integer)
        ' Get movie to delete
        Dim movieToDelete As Movie = _db.MovieSet.First(Function(m) m.Id = id)

        ' Delete 
        _db.DeleteObject(movieToDelete)
        _db.SaveChanges()

        ' Show Index view
        Return RedirectToAction("Index")
    End Function

End Class

Действие Delete() сначала извлекает сущность Movie, которая соответствует идентификатору, переданного действию. Затем фильм удаляется из базы данных путем вызова метода DeleteObject(), за которым следует метод SaveChanges(). Наконец, пользователь перенаправляется обратно в представление индекса.

Итоги

Цель этого руководства — продемонстрировать, как можно создавать веб-приложения на основе базы данных, используя преимущества ASP.NET MVC и Microsoft Entity Framework. Вы узнали, как создать приложение, которое позволяет выбирать, вставлять, обновлять и удалять записи базы данных.

Во-первых, мы рассмотрели, как можно использовать мастер моделей entity data для создания модели entity data из Visual Studio. Далее вы узнаете, как использовать LINQ to Entities для получения набора записей базы данных из таблицы базы данных. Наконец, мы использовали Entity Framework для вставки, обновления и удаления записей базы данных.