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

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

Note

Обновленная версия этого учебника доступна здесь , в которой используется ASP.NET MVC 5 и Visual Studio 2013.An updated version of this tutorial is available here that uses ASP.NET MVC 5 and Visual Studio 2013. Он более безопасен, гораздо проще следовать и демонстрирует дополнительные функции.It's more secure, much simpler to follow and demonstrates more features.

В этом учебнике вы узнаете об основах создания веб-приложения 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 C# Web Developer с исходным кодом.A Visual Web Developer project with C# source code is available to accompany this topic. Скачайте C# версию.Download the C# version. Если вы предпочитаете Visual Basic, переключитесь на Visual Basic версию этого учебника.If you prefer Visual Basic, switch to the Visual Basic 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 string Rating { get; set; }

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

public class Movie
{
    public int      ID          { get; set; }
    public string   Title       { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string   Genre       { get; set; }
    public decimal  Price       { get; set; }
    public string   Rating      { get; set; }
}

Перекомпилируйте приложение с помощью команды меню " отладка >создать ролик ".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.cshtml and \Views\Movies\Create.cshtml view templates in order to support the new Rating property.

Откройте файл \виевс\мовиес\индекс.кштмл и добавьте заголовок столбца <th>Rating</th> сразу после столбца Price .Open the \Views\Movies\Index.cshtml 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. cshtml :Below is what the updated Index.cshtml view template looks like:

<table>
    <tr>
        <th></th>
        <th>Title</th>
        <th>Release Date</th>
        <th>Genre</th>
        <th>Price</th>
        <th>Rating</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Rating   )
        </td>
        <td>
            @Html.ActionLink("Edit Me", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
}
</table>

Затем откройте файл \виевс\мовиес\креате.кштмл и добавьте следующую разметку в конец формы.Next, open the \Views\Movies\Create.cshtml 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(model => model.Rating)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Rating)
    @Html.ValidationMessageFor(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;
using System.Collections.Generic;
using System.Data.Entity;

namespace MvcMovie.Models {
    public class MovieInitializer : DropCreateDatabaseIfModelChanges<MovieDBContext> {
        protected override void Seed(MovieDBContext context) {
            var movies = new List<Movie> {  
  
                 new Movie { Title = "When Harry Met Sally",   
                             ReleaseDate=DateTime.Parse("1989-1-11"),   
                             Genre="Romantic Comedy",  
                             Rating="R",  
                             Price=7.99M},  

                     new Movie { Title = "Ghostbusters ",   
                             ReleaseDate=DateTime.Parse("1984-3-13"),   
                             Genre="Comedy",  
                              Rating="R",  
                             Price=8.99M},   
  
                 new Movie { Title = "Ghostbusters 2",   
                             ReleaseDate=DateTime.Parse("1986-2-23"),   
                             Genre="Comedy",  
                             Rating="R",  
                             Price=9.99M},   

               new Movie { Title = "Rio Bravo",   
                             ReleaseDate=DateTime.Parse("1959-4-15"),   
                             Genre="Western",  
                             Rating="R",  
                             Price=3.99M},   
             };

            movies.ForEach(d => context.Movies.Add(d));
        }
    }
}

Класс 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.

Давайте добавим два оператора using в начало файла.Let's add two using statements to the top of the file. Первый элемент ссылается на пространство имен Entity Framework, а второй ссылается на пространство имен, где живет наш класс MovieInitializer:The first references the Entity Framework namespace, and the second references the namespace where our MovieInitializer class lives:

using System.Data.Entity;            // Database.SetInitialize
using MvcMovie.Models;              // MovieInitializer

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

protected void Application_Start()
{
    Database.SetInitializer<MovieDBContext>(new MovieInitializer());

    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

Только что добавленная инструкция 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_SM7_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.