Добавление нового поля

Rick Anderson

В этой статье мы используем Code First Migrations Entity Framework, чтобы внести некоторые изменения в классы модели, чтобы изменения применялись к БД.

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

Добавление свойства Rating в модель Movie

Откройте файл Models/Movie.cs и добавьте свойство Rating:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
    public string Rating { get; set; }
}

Соберите приложение (Ctrl+Shift+B).

Поскольку вы добавили новое поле в класс Movie, вам нужно обновить и Binding whitelist, чтобы сюда было включено новое свойство. Обновите атрибут [Bind] для методов Create и Edit, чтобы в них присутствовало свойство Rating:

[Bind("ID,Title,ReleaseDate,Genre,Price,Rating")]

Также вам нужно обновить представления, чтобы отображать, создавать и редактировать новое свойство Rating в представлении браузера.

Отредактируйте файл /Views/Movies/Index.cshtml и добавьте поле Rating:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Genre)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Rating)
        </th>
        <th></th>
    </tr>
    
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Rating)
        </td>
        <td>

Обновите /Views/Movies/Create.cshtml полем Rating. Вы можете скопировать/вставить “form group” и позволить intelliSense помочь вам обновить эти поля. IntelliSense работает с Tag Helpers.

../../_images/cr.png

Изменения представлены ниже:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<form asp-action="Create">
    <div class="form-horizontal">
        <h4>Movie</h4>
        <hr />
        <div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Genre" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Genre" class="form-control" />
                <span asp-validation-for="Genre" class="text-danger" />
            </div>
        </div>
    @*Markup removed for brevity.*@
        <div class="form-group">
            <label asp-for="Rating" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Rating" class="form-control" />
                <span asp-validation-for="Rating" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

Приложение не будет работать, пока мы не обновим БД, чтобы в нее было включено новое поле. Если вы запустите его сейчас, вы получите следующее SqlException:

../../_images/se.png

Вы видите эту ошибку, потому что обновленный модельный класс Movie в приложении теперь отличается от схемы таблицы Movie существующей БД. (В БД нет колонки Rating.)

Эту проблему можно исправить разными способами:

  1. Entity Framework автоматически может пересоздать БД, основываясь на новой схеме классов модели. Такой подход очень удобен на ранней стадии разработки, особенно если вы активно работаете с тестовой БД; это позволяет вам быстро синхронизировать модель и схему БД. С другой стороны, вы теряете существующие данные из БД — так что вам не стоит использовать такой подход на производственной БД! Автоматическое заполнение БД тестовыми данными часто является отличным способом при разработке приложений.
  2. Напрямую изменить схему в существующей БД, чтобы она соответствовала классам модели. Преимущество такого подхода состоит в том, что вы сохраняете данные. Вы можете сделать это вручную или создать специальный скрипт для внесения изменений в БД.
  3. Использование Code First Migrations для обновления схемы БД.

В этом руководстве мы используем Code First Migrations.

Обновите класс SeedData, чтобы он предоставлял значение для новой колонки. Простое изменение показано ниже, но вы сделаете такое изменение для каждого new Movie.

1
2
3
4
5
6
7
8
         new Movie
         {
             Title = "Ghostbusters ",
             ReleaseDate = DateTime.Parse("1984-3-13"),
             Genre = "Comedy",
             Rating = "G",
             Price = 8.99M
         },

Соберите приложение и откройте командную строку. Введите следующие команды:

dnx ef migrations add Rating
dnx ef database update

Команда migrations add говорит фреймворку миграции проверить текущую модель Movie и текущую схему БД Movie, а также создать необходимый код для миграции БД в новую модель. Имя “Rating” является произвольным, и оно используется для названия миграционного файла. В данном случае полезно использовать значимое имя.

Если вы удалите все записи из БД, инициализатор заполнит БД и включит поле Rating. Вы можете сделать это с помощью ссылок delete в браузере или из SSOX.

Запустите приложение и проверьте, что вы можете создавать/редактировать/отображать ролики полем Rating. Также вы должны добавить поле Rating в представление Edit, Details и Delete.

Поделись хорошей новостью с друзьями!
Следи за новостями!