Добавление нового поля в модель Movie и таблицу базы данных (VB)Adding a New Field to the Movie Model and Database Table (VB)

по Рик Андерсон (by Rick Anderson

В этом учебнике вы узнаете об основах создания веб-приложения ASP.NET MVC с помощью Microsoft Visual Web Developer 2010 Express с пакетом обновления 1 (SP1), который является бесплатной версией Microsoft Visual Studio.This tutorial will teach you the basics of building an ASP.NET MVC Web application using Microsoft Visual Web Developer 2010 Express Service Pack 1, which is a free version of Microsoft Visual Studio. Прежде чем начать, убедитесь, что установлены предварительные требования, перечисленные ниже.Before you start, make sure you've installed the prerequisites listed below. Чтобы установить все эти компоненты, щелкните следующую ссылку: установщик веб-платформы.You can install all of them by clicking the following link: Web Platform Installer. Кроме того, вы можете отдельно установить необходимые компоненты, используя следующие ссылки:Alternatively, you can individually install the prerequisites using the following links:

Если вы используете Visual Studio 2010 вместо Visual Web Developer 2010, установите необходимые компоненты, щелкнув следующую ссылку: Предварительные требования для Visual studio 2010.If you're using Visual Studio 2010 instead of Visual Web Developer 2010, install the prerequisites by clicking the following link: Visual Studio 2010 prerequisites.

Для этого раздела доступен проект Visual Web Developer с исходным кодом VB.NET.A Visual Web Developer project with VB.NET source code is available to accompany this topic. Скачайте версию VB.NET.Download the VB.NET version. При желании C#переключитесь на C# версию этого учебника.If you prefer C#, switch to the C# version of this tutorial.

В этом разделе вы внесете некоторые изменения в классы модели и узнаете, как можно обновить схему базы данных в соответствии с изменениями модели.In this section you'll make some changes to the model classes and learn how you can update the database schema to match the model changes.

Добавление свойства Rating в модель MovieAdding a Rating Property to the Movie Model

Для начала добавьте новое свойство Rating в существующий класс Movie.Start by adding a new Rating property to the existing Movie class. Откройте файл Movie.CS и добавьте свойство Rating следующим образом:Open the Movie.cs file and add the Rating property like this one:

Public Property Rating() As String

Теперь полный Movie класс выглядит следующим образом:The complete Movie class now looks like the following code:

Public Class Movie
    Public Property ID() As Integer
    Public Property Title() As String
    Public Property ReleaseDate() As Date
    Public Property Genre() As String
    Public Property Price() As Decimal
    Public Property Rating() As String
End Class

Перекомпилируйте приложение с помощью команды меню " отладка >создать ролик ".Recompile the application using the Debug >Build Movie menu command.

Теперь, когда вы обновили класс Model, вам также потребуется обновить шаблоны представления \виевс\мовиес\индекс.вбхтмл и \виевс\мовиес\креате.вбхтмл , чтобы обеспечить поддержку нового свойства Rating.Now that you've updated the Model class, you also need to update the \Views\Movies\Index.vbhtml and \Views\Movies\Create.vbhtml view templates in order to support the new Rating property.

Откройте файл\виевс\мовиес\индекс.вбхтмл и добавьте заголовок столбца <th>Rating</th> сразу после столбца Price .Open the\Views\Movies\Index.vbhtml file and add a <th>Rating</th> column heading just after the Price column. Затем добавьте <td> столбец рядом с концом шаблона, чтобы отобразить значение @item.Rating.Then add a <td> column near the end of the template to render the @item.Rating value. Ниже показано, как выглядит обновленный шаблон представления index. vbhtml .Below is what the updated Index.vbhtml view template looks like:

<table>
    <tr>
        <th>            Title        </th>
        <th>            ReleaseDate        </th>
        <th>            Genre        </th>
        <th>            Price        </th>
        <th>Rating</th>
        <th></th>
    </tr>

@For Each item In Model
    Dim currentItem = item
    @<tr>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Title)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Genre)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Price)
        </td>
         <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Rating)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", New With {.id = currentItem.ID}) |
            @Html.ActionLink("Details", "Details", New With {.id = currentItem.ID}) |
            @Html.ActionLink("Delete", "Delete", New With {.id = currentItem.ID})
        </td>
    </tr>
Next

</table>

Затем откройте файл \виевс\мовиес\креате.вбхтмл и добавьте следующую разметку в конец формы.Next, open the \Views\Movies\Create.vbhtml file and add the following markup near the end of the form. При этом текстовое поле подготавливается к просмотру, что позволяет указать рейтинг при создании нового фильма.This renders a text box so that you can specify a rating when a new movie is created.

<div class="editor-label">
     @Html.LabelFor(Function(model) model.Rating)
 </div>
 <div class="editor-field">
     @Html.EditorFor(Function(model) model.Rating)
     @Html.ValidationMessageFor(Function(model) model.Rating)
 </div>

Управление различиями в модели и схеме базы данныхManaging Model and Database Schema Differences

Теперь вы обновили код приложения для поддержки нового свойства Rating.You've now updated the application code to support the new Rating property.

Теперь запустите приложение и перейдите по URL-адресу /Movies .Now run the application and navigate to the /Movies URL. При этом вы увидите следующую ошибку:When you do this, though, you'll see the following error:

Эта ошибка возникает, поскольку обновленный класс модели Movie в приложении теперь отличается от схемы Movie таблицы существующей базы данных.You're seeing this error because the updated Movie model class in the application is now different than the schema of the Movie table of the existing database. (В таблице базы данных отсутствует столбец Rating.)(There's no Rating column in the database table.)

По умолчанию при использовании Entity Framework Code First для автоматического создания базы данных, как это было сделано ранее в этом руководстве, Code First добавляет таблицу в базу данных, чтобы определить, синхронизирована ли схема базы данных с классами модели, из которых она была создана.By default, when you use Entity Framework Code First to automatically create a database, as you did earlier in this tutorial, Code First adds a table to the database to help track whether the schema of the database is in sync with the model classes it was generated from. Если они не синхронизированы, Entity Framework выдает ошибку.If they aren't in sync, the Entity Framework throws an error. Это упрощает отслеживание проблем во время разработки, которые в противном случае могут быть найдены (путем маскировки ошибок) во время выполнения.This makes it easier to track down issues at development time that you might otherwise only find (by obscure errors) at run time. Функция проверки синхронизации — это то, что приводит к отображению сообщения об ошибке, которое вы только что видели.The sync-checking feature is what causes the error message to be displayed that you just saw.

Существует два подхода к устранению этой ошибки:There are two approaches to resolving the error:

  1. Можно с помощью Entity Framework автоматически удалить и повторно создать базу данных на основе новой схемы класса модели.Have the Entity Framework automatically drop and re-create the database based on the new model class schema. Этот подход очень удобен при выполнении активной разработки в тестовой базе данных, так как позволяет быстро развивать модель и схему базы данных вместе.This approach is very convenient when doing active development on a test database, because it allows you to quickly evolve the model and database schema together. Недостаток этого подхода заключается в том, что в базе данных теряются существующие данные — поэтому вы не хотите использовать этот подход в рабочей базе данных!The downside, though, is that you lose existing data in the database — so you don't want to use this approach on a production database!
  2. Можно явно изменить схему существующей базы данных в соответствии с новыми классами модели.Explicitly modify the schema of the existing database so that it matches the model classes. Преимущество такого подхода состоит в том, что сохраняются все данные.The advantage of this approach is that you keep your data. Это изменение можно выполнить как вручную, так и с помощью соответствующего скрипта базы данных.You can make this change either manually or by creating a database change script.

В этом руководстве мы будем использовать первый подход — у вас будет Entity Framework Code First автоматически воссоздать базу данных в любое время при изменении модели.For this tutorial, we'll use the first approach — you'll have the Entity Framework Code First automatically re-create the database anytime the model changes.

Автоматическое повторное создание базы данных при изменении моделиAutomatically Re-Creating the Database on Model Changes

Теперь обновите приложение таким образом, чтобы Code First автоматически удалят и повторно создает базу данных в любое время, когда вы изменяете модель для приложения.Let's update the application so that Code First automatically drops and re-creates the database anytime you change the model for the application.

Note

Предупреждение об ошибке Этот подход следует включать для автоматического удаления и повторного создания базы данных только при использовании базы данных разработки или тестирования, а не в рабочей базе данных, содержащей реальные данные.Warning You should enable this approach of automatically dropping and re-creating the database only when you're using a development or test database, and never on a production database that contains real data. Использование на рабочем сервере может привести к утрате данных.Using it on a production server can lead to data loss.

В Обозреватель решенийщелкните правой кнопкой мыши папку модели , выберите добавить, а затем выберите класс.In Solution Explorer, right click the Models folder, select Add, and then select Class.

Присвойте классу имя "Мовиеинитиализер".Name the class "MovieInitializer". Обновите класс MovieInitializer, чтобы он содержал следующий код:Update the MovieInitializer class to contain the following code:

using System;
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity

Namespace MvcMovie.Models
    Public Class MovieInitializer
        Inherits DropCreateDatabaseIfModelChanges(Of MovieDBContext)
        Protected Overrides Sub Seed(ByVal context As MovieDBContext)
            Dim movies = New List(Of Movie) From {
             New Movie With {.Title = "When Harry Met Sally", .ReleaseDate = Date.Parse("1989-1-11"), .Genre = "Romantic Comedy", .Rating = "R", .Price = 7.99D},
             New Movie With {.Title = "Ghostbusters ", .ReleaseDate = Date.Parse("1984-3-13"), .Genre = "Comedy", .Rating = "R", .Price = 8.99D},
             New Movie With {.Title = "Ghostbusters 2", .ReleaseDate = Date.Parse("1986-2-23"), .Genre = "Comedy", .Rating = "R", .Price = 9.99D},
             New Movie With {.Title = "Rio Bravo", .ReleaseDate = Date.Parse("1959-4-15"), .Genre = "Western", .Rating = "R", .Price = 3.99D}}

            movies.ForEach(Function(d) context.Movies.Add(d))
        End Sub
    End Class
End Namespace

Класс MovieInitializer указывает, что база данных, используемая моделью, должна быть удалена и автоматически создана повторно, если классы модели когда-либо изменяются.The MovieInitializer class specifies that the database used by the model should be dropped and automatically re-created if the model classes ever change. Код включает метод Seed для указания некоторых данных по умолчанию, которые автоматически добавляются в базу данных при каждом ее создании (или повторном создании).The code includes a Seed method to specify some default data to automatically add to the database any time it's created (or re-created). Это позволяет получить удобный способ заполнения базы данных несколькими демонстрационными данными без необходимости вручную заполнять ее при каждом изменении модели.This provides a useful way to populate the database with some sample data, without requiring you to manually populate it each time you make a model change.

Теперь, когда вы определили класс MovieInitializer, вы хотите подключить его таким образом, чтобы при каждом запуске приложения он проверял, отличаются ли классы модели от схемы в базе данных.Now that you've defined the MovieInitializer class, you'll want to wire it up so that each time the application runs, it checks whether the model classes are different from the schema in the database. Если это так, можно запустить инициализатор, чтобы повторно создать базу данных в соответствии с моделью и затем заполнить базу данных образцом данных.If they are, you can run the initializer to re-create the database to match the model and then populate the database with the sample data.

Откройте файл Global. asax в корне проекта MvcMovies:Open the Global.asax file that's at the root of the MvcMovies project:

Файл Global. asax содержит класс, который определяет все приложение для проекта, и содержит обработчик событий Application_Start, который выполняется при первом запуске приложения.The Global.asax file contains the class that defines the entire application for the project, and contains an Application_Start event handler that runs when the application first starts.

Найдите метод Application_Start и добавьте вызов Database.SetInitializer в начале метода, как показано ниже:Find the Application_Start method and add a call to Database.SetInitializer at the beginning of the method, as shown below:

Sub Application_Start()
        System.Data.Entity.Database.SetInitializer(Of MovieDBContext)(New MvcMovie.Models.MovieInitializer())
       
        AreaRegistration.RegisterAllAreas()

        RegisterGlobalFilters(GlobalFilters.Filters)
        RegisterRoutes(RouteTable.Routes)
    End Sub

Только что добавленная инструкция Database.SetInitializer указывает, что база данных, используемая экземпляром MovieDBContext, должна автоматически удаляться и создаваться повторно, если схема и база данных не совпадают.The Database.SetInitializer statement you just added indicates that the database used by the MovieDBContext instance should be automatically deleted and re-created if the schema and the database don't match. Как вы видели, он также заполняет базу данных образцом данных, указанным в классе MovieInitializer.And as you saw, it will also populate the database with the sample data that's specified in the MovieInitializer class.

Закройте файл Global. asax .Close the Global.asax file.

Повторно запустите приложение и перейдите по URL-адресу /Movies .Re-run the application and navigate to the /Movies URL. При запуске приложение обнаруживает, что структура модели больше не соответствует схеме базы данных.When the application starts, it detects that the model structure no longer matches the database schema. Она автоматически повторно создает базу данных в соответствии с новой структурой модели и заполняет базу данных образцами фильмов:It automatically re-creates the database to match the new model structure and populates the database with the sample movies:

7_MyMovieList_SM

Щелкните ссылку создать , чтобы добавить новый фильм.Click the Create New link to add a new movie. Обратите внимание, что можно добавить оценку.Note that you can add a rating.

7_CreateRioII7_CreateRioII

Нажмите кнопку Создать.Click Create. Теперь новый фильм, включая рейтинг, отображается в списке фильмов:The new movie, including the rating, now shows up in the movies listing:

7_ourNewMovie_SM

В этом разделе вы узнали, как можно изменить объекты модели и синхронизировать базу данных с изменениями.In this section you saw how you can modify model objects and keep the database in sync with the changes. Вы также узнали, как заполнить созданную базу данных образцами данных, чтобы вы могли испытать сценарии.You also learned a way to populate a newly created database with sample data so you can try out scenarios. Теперь рассмотрим, как можно добавить расширенную логику проверки к классам модели и обеспечить применение некоторых бизнес-правил.Next, let's look at how you can add richer validation logic to the model classes and enable some business rules to be enforced.