Udostępnij za pośrednictwem


Dodawanie nowego pola do modelu Movie i tabeli (C#)

Autor: Rick Anderson

Uwaga

Zaktualizowana wersja tego samouczka jest dostępna tutaj , która używa ASP.NET MVC 5 i Visual Studio 2013. Jest bezpieczniejszy, znacznie prostszy do naśladowania i demonstruje więcej funkcji.

Ten samouczek zawiera podstawowe informacje na temat tworzenia aplikacji internetowej MVC ASP.NET przy użyciu dodatku Microsoft Visual Web Developer 2010 Express Service Pack 1, który jest bezpłatną wersją programu Microsoft Visual Studio. Przed rozpoczęciem upewnij się, że zostały zainstalowane wymagania wstępne wymienione poniżej. Wszystkie te elementy można zainstalować, klikając następujący link: Instalator platformy internetowej. Alternatywnie można indywidualnie zainstalować wymagania wstępne, korzystając z następujących linków:

Jeśli używasz programu Visual Studio 2010 zamiast Visual Web Developer 2010, zainstaluj wymagania wstępne, klikając następujący link: Wymagania wstępne programu Visual Studio 2010.

Projekt Visual Web Developer z kodem źródłowym języka C# jest dostępny do dołączenia do tego tematu. Pobierz wersję języka C#. Jeśli wolisz visual basic, przejdź do wersji Visual Basic tego samouczka.

W tej sekcji wprowadzisz pewne zmiany w klasach modeli i dowiesz się, jak zaktualizować schemat bazy danych, aby dopasować go do zmian modelu.

Dodawanie właściwości ratingu do modelu filmowego

Zacznij od dodania nowej Rating właściwości do istniejącej Movie klasy. Otwórz plik Movie.cs i dodaj Rating właściwość w następujący sposób:

public string Rating { get; set; }

Kompletna Movie klasa wygląda teraz jak następujący kod:

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; }
}

Skompiluj ponownie aplikację przy użyciu polecenia menu Debuguj >film kompilacji.

Po zaktualizowaniu Model klasy należy również zaktualizować szablony widoków \Views\Movies\Index.cshtml i \Views\Movies\Create.cshtml , aby obsługiwać nową Rating właściwość.

Otwórz plik \Views\Movies\Index.cshtml i dodaj <th>Rating</th> nagłówek kolumny tuż po kolumnie Cena. Następnie dodaj kolumnę <td> pod koniec szablonu, aby renderować @item.Rating wartość. Poniżej przedstawiono wygląd zaktualizowanego szablonu widoku Index.cshtml :

<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>

Następnie otwórz plik \Views\Movies\Create.cshtml i dodaj następujący znacznik na końcu formularza. Spowoduje to renderowanie pola tekstowego, aby można było określić ocenę podczas tworzenia nowego filmu.

<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>

Zarządzanie różnicami między modelem i schematem bazy danych

Kod aplikacji został zaktualizowany w celu obsługi nowej Rating właściwości.

Teraz uruchom aplikację i przejdź do adresu URL /Movies . Gdy jednak to zrobisz, zostanie wyświetlony następujący błąd:

Zrzut ekranu przedstawiający okno przeglądarki z błędem wskazującym błąd serwera w aplikacji.

Ten błąd występuje, ponieważ zaktualizowana Movie klasa modelu w aplikacji różni się teraz od schematu Movie tabeli istniejącej bazy danych. (W tabeli bazy danych nie Rating ma żadnej kolumny).

Domyślnie gdy używasz programu Entity Framework Code First do automatycznego tworzenia bazy danych, tak jak wcześniej w tym samouczku, funkcja Code First dodaje tabelę do bazy danych, aby ułatwić śledzenie, czy schemat bazy danych jest zsynchronizowany z klasami modelu, z których została wygenerowana. Jeśli nie są one zsynchronizowane, program Entity Framework zgłasza błąd. Ułatwia to śledzenie problemów w czasie programowania, które w przeciwnym razie można znaleźć tylko (przez niejasne błędy) w czasie wykonywania. Funkcja sprawdzania synchronizacji powoduje wyświetlenie właśnie wyświetlonego komunikatu o błędzie.

Istnieją dwa podejścia do rozwiązywania błędu:

  1. Program Entity Framework automatycznie upuść i ponownie utworzyć bazę danych na podstawie nowego schematu klasy modelu. Takie podejście jest bardzo wygodne podczas aktywnego programowania w testowej bazie danych, ponieważ umożliwia szybkie rozwijanie modelu i schematu bazy danych. Wadą jest jednak utratę istniejących danych w bazie danych — więc nie chcesz używać tego podejścia w produkcyjnej bazie danych.
  2. Jawnie zmodyfikuj schemat istniejącej bazy danych, tak aby odpowiadał klasom modelu. Zaletą tego podejścia jest przechowywanie danych. Tę zmianę można wprowadzić ręcznie lub tworząc skrypt zmiany bazy danych.

Na potrzeby tego samouczka użyjemy pierwszego podejścia — najpierw ponownie utworzysz bazę danych za każdym razem, gdy zmieni się model.

Automatyczne ponowne tworzenie bazy danych w przypadku zmian modelu

Zaktualizujmy aplikację, aby funkcja Code First automatycznie spadała i ponownie tworzy bazę danych w dowolnym momencie zmiany modelu dla aplikacji.

Uwaga

Ostrzeżenie Należy włączyć to podejście automatycznego usuwania i ponownego tworzenia bazy danych tylko wtedy, gdy używasz programowania lub testowej bazy danych, a nigdy w produkcyjnej bazie danych zawierającej rzeczywiste dane. Użycie go na serwerze produkcyjnym może prowadzić do utraty danych.

W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder Models, wybierz polecenie Dodaj, a następnie wybierz pozycję Klasa.

Zrzut ekranu przedstawiający okno Eksplorator rozwiązań. W menu kliknij prawym przyciskiem myszy pozycję Dodaj. Klasa jest zaznaczona w menu podrzędnym.

Nadaj klasie nazwę "MovieInitializer". Zaktualizuj klasę tak MovieInitializer , aby zawierała następujący kod:

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));
        }
    }
}

Klasa MovieInitializer określa, że baza danych używana przez model powinna zostać porzucona i automatycznie utworzona ponownie, jeśli kiedykolwiek zmienią się klasy modelu. Kod zawiera metodę określania Seed niektórych domyślnych danych, które mają być automatycznie dodawane do bazy danych za każdym razem, gdy zostaną utworzone (lub utworzone ponownie). Zapewnia to przydatny sposób wypełniania bazy danych przykładowymi danymi bez konieczności ręcznego wypełniania jej za każdym razem, gdy wprowadzisz zmianę modelu.

Po zdefiniowaniu MovieInitializer klasy należy połączyć ją tak, aby za każdym razem, gdy aplikacja działa, sprawdza, czy klasy modelu różnią się od schematu w bazie danych. Jeśli tak, możesz uruchomić inicjator, aby ponownie utworzyć bazę danych, aby dopasować go do modelu, a następnie wypełnić bazę danych przykładowymi danymi.

Otwórz plik Global.asax znajdujący się w katalogu głównym MvcMovies projektu:

Zrzut ekranu przedstawiający kartę Global dot asax dot c s. Globalna kropka asax jest okrągła w kolorze czerwonym w oknie Eksplorator rozwiązań.

Plik Global.asax zawiera klasę, która definiuje całą aplikację dla projektu i zawiera procedurę obsługi zdarzeń uruchamianą Application_Start po pierwszym uruchomieniu aplikacji.

Dodajmy dwie instrukcje using na początku pliku. Pierwsza odwołuje się do przestrzeni nazw programu Entity Framework, a druga odwołuje się do przestrzeni nazw, w której znajduje się nasza MovieInitializer klasa:

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

Następnie znajdź metodę Application_Start i dodaj wywołanie na Database.SetInitializer początku metody, jak pokazano poniżej:

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

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

Właśnie Database.SetInitializer dodana instrukcja wskazuje, że baza danych używana przez MovieDBContext wystąpienie powinna zostać automatycznie usunięta i utworzona ponownie, jeśli schemat i baza danych nie są zgodne. Jak widać, baza danych zostanie również wypełniona przykładowymi danymi określonymi MovieInitializer w klasie.

Zamknij plik Global.asax.

Uruchom ponownie aplikację i przejdź do adresu URL /Movies . Po uruchomieniu aplikacji wykrywa ona, że struktura modelu nie jest już zgodna ze schematem bazy danych. Automatycznie tworzy ponownie bazę danych w celu dopasowania jej do nowej struktury modelu i wypełnia bazę danych przykładowymi filmami:

7_MyMovieList_SM

Kliknij link Utwórz nowy, aby dodać nowy film. Pamiętaj, że możesz dodać ocenę.

7_CreateRioII

Kliknij pozycję Utwórz. Nowy film, w tym ocena, teraz pojawia się na liście filmów:

7_ourNewMovie_SM

W tej sekcji przedstawiono sposób modyfikowania obiektów modelu i synchronizowania bazy danych ze zmianami. Przedstawiono również sposób wypełniania nowo utworzonej bazy danych przykładowymi danymi, dzięki czemu można wypróbować scenariusze. Następnie przyjrzyjmy się temu, jak można dodać bogatszą logikę walidacji do klas modeli i umożliwić wymuszanie niektórych reguł biznesowych.