Dodawanie modelu do aplikacji ASP.NET Core MVCAdd a model to an ASP.NET Core MVC app

Przez Rick Anderson i Tom DykstraBy Rick Anderson and Tom Dykstra

W tej sekcji dodasz klasy zarządzania filmów w bazie danych.In this section, you add classes for managing movies in a database. Te klasy będzie "Modelu" wchodzi w skład MVC aplikacji.These classes will be the "Model" part of the MVC app.

Użyj tych klas z Entity Framework Core (EF Core) do pracy z bazą danych.You use these classes with Entity Framework Core (EF Core) to work with a database. EF Core to platforma mapowania obiektowo relacyjny (ORM), która upraszcza kod dostępu do danych, który trzeba napisać.EF Core is an object-relational mapping (ORM) framework that simplifies the data access code that you have to write.

Klasy modeli, możesz utworzyć są nazywane klasami POCO (z Pzwykły Old CLR Obiekty), ponieważ nie mają żadnych zależności EF Core.The model classes you create are known as POCO classes (from Plain Old CLR Objects) because they don't have any dependency on EF Core. Określają one po prostu właściwości danych, które będą przechowywane w bazie danych.They just define the properties of the data that will be stored in the database.

W tym samouczku pisania klasy modeli i programem EF Core tworzy bazę danych.In this tutorial, you write the model classes first, and EF Core creates the database. Alternatywnym podejściu, nieuwzględnione w tym miejscu jest do generowania klasy modelu z istniejącej bazy danych.An alternate approach not covered here is to generate model classes from an existing database. Aby uzyskać informacji na temat tego podejścia, zobacz ASP.NET Core — istniejąca baza danych.For information about that approach, see ASP.NET Core - Existing Database.

Dodaj klasę modelu danychAdd a data model class

Kliknij prawym przyciskiem myszy modeli folder > Dodaj > klasy.Right-click the Models folder > Add > Class. Nazwa klasy filmu.Name the class Movie.

Dodaj następujące właściwości do Movie klasy:Add the following properties to the Movie class:

using System;
using System.ComponentModel.DataAnnotations;

namespace MvcMovie.Models
{
    public class Movie
    {
        public int Id { get; set; }
        public string Title { get; set; }

        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }
        public string Genre { get; set; }
        public decimal Price { get; set; }
    }
}

Movie Klasa zawiera:The Movie class contains:

  • Id Pola, które jest wymagane przez bazę danych dla klucza podstawowego.The Id field which is required by the database for the primary key.

  • [DataType(DataType.Date)]: DataType atrybut określa typ danych (Date).[DataType(DataType.Date)]: The DataType attribute specifies the type of the data (Date). Z tego atrybutu:With this attribute:

    • Użytkownik nie musi wprowadzić informacje o czasie w polu daty.The user is not required to enter time information in the date field.
    • Tylko data jest wyświetlany, nie czas informacji.Only the date is displayed, not time information.

DataAnnotations zostały omówione później w samouczku.DataAnnotations are covered in a later tutorial.

Tworzenie szkieletu modelu movieScaffold the movie model

W tej sekcji modelu movie jest szkielet.In this section, the movie model is scaffolded. Oznacza to, że narzędzie do tworzenia szkieletów tworzy strony dla operacji tworzenia, odczytu, aktualizowania lub usuwania (CRUD) do modelu movie.That is, the scaffolding tool produces pages for Create, Read, Update, and Delete (CRUD) operations for the movie model.

W Eksploratora rozwiązań, kliknij prawym przyciskiem myszy kontrolerów folderu > Dodaj > Nowy element szkieletu.In Solution Explorer, right-click the Controllers folder > Add > New Scaffolded Item.

Widok powyżej kroku

W Dodawanie szkieletu okno dialogowe, wybierz opcję kontroler MVC z widokami używający narzędzia Entity Framework > Dodaj.In the Add Scaffold dialog, select MVC Controller with views, using Entity Framework > Add.

Dodaj okno dialogowe Tworzenie szkieletu

Wykonaj Dodaj kontroler okno dialogowe:Complete the Add Controller dialog:

  • Klasa modelu: Film (MvcMovie.Models)Model class: Movie (MvcMovie.Models)
  • Klasa kontekstu danych: Wybierz + ikonę i Dodaj domyślny MvcMovie.Models.MvcMovieContextData context class: Select the + icon and add the default MvcMovie.Models.MvcMovieContext

Dodawanie kontekstu danych

  • Widoki: Zachowaj wartość domyślną każdego z zaznaczoną opcjąViews: Keep the default of each option checked
  • Nazwa kontrolera: Zachowaj wartość domyślną MoviesControllerController name: Keep the default MoviesController
  • Wybierz DodajSelect Add

Dodaj kontroler, okno dialogowe

Program Visual Studio tworzy:Visual Studio creates:

  • Entity Framework Core bazy danych klasy kontekstu (Data/MvcMovieContext.cs)An Entity Framework Core database context class (Data/MvcMovieContext.cs)
  • Kontroler filmy (Controllers/MoviesController.cs)A movies controller (Controllers/MoviesController.cs)
  • Pliki widoku razor dla stron Create, Delete, szczegółowe informacje, edycji i indeksu (widoków/filmy/*.cshtml)Razor view files for Create, Delete, Details, Edit, and Index pages (Views/Movies/*.cshtml)

Automatyczne tworzenie kontekst bazy danych i CRUD (tworzenia, odczytu, aktualizacji i usuwania) metody akcji i widoki są określane jako tworzenia szkieletów.The automatic creation of the database context and CRUD (create, read, update, and delete) action methods and views is known as scaffolding.

Jeśli Uruchom aplikację i kliknąć filmu Mvc link, zostanie wyświetlony komunikat o błędzie podobny do następującego:If you run the app and click on the Mvc Movie link, you get an error similar to the following:

An unhandled exception occurred while processing the request.

SqlException: Cannot open database "MvcMovieContext-<GUID removed>" requested by the login. The login failed.
Login failed for user 'Rick'.

System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString

Należy utworzyć bazę danych, a następnie użyj programu EF Core migracje funkcję, aby to zrobić.You need to create the database, and you use the EF Core Migrations feature to do that. Migracje umożliwia tworzenie bazy danych, która pasuje do modelu danych i zaktualizować schemat bazy danych, gdy model danych, zmiany.Migrations lets you create a database that matches your data model and update the database schema when your data model changes.

Początkowej migracjiInitial migration

W tej sekcji należy wykonać następujące zadania:In this section, the following tasks are completed:

  • Dodaj początkowej migracji.Add an initial migration.
  • Zaktualizuj bazy danych przy użyciu początkowej migracji.Update the database with the initial migration.
  1. Z narzędzia menu, wybierz opcję Menedżera pakietów NuGet > Konsola Menedżera pakietów (PMC).From the Tools menu, select NuGet Package Manager > Package Manager Console (PMC).

    Menu konsoli zarządzania Pakietami

  2. W konsoli zarządzania Pakietami wprowadź następujące polecenia:In the PMC, enter the following commands:

    Add-Migration Initial
    Update-Database
    

    Add-Migration Polecenie generuje kod, aby utworzyć schemat początkowej bazy danych.The Add-Migration command generates code to create the initial database schema.

    Schemat bazy danych zależy od określonego w modelu MvcMovieContext klasy.The database schema is based on the model specified in the MvcMovieContext class. Initial Argument jest nazwą migracji.The Initial argument is the migration name. Można dowolną nazwę, ale zgodnie z Konwencją, jest używany na nazwę opisującą migracji.Any name can be used, but by convention, a name that describes the migration is used. Aby uzyskać więcej informacji, zobacz Samouczek: Za pomocą funkcji migracje — ASP.NET MVC z programem EF Core.For more information, see Samouczek: Za pomocą funkcji migracje — ASP.NET MVC z programem EF Core.

    Update-Database Polecenia Up method in Class metoda migracje / {sygnatura czasowa} _InitialCreate.cs pliku, który tworzy bazę danych.The Update-Database command runs the Up method in the Migrations/{time-stamp}_InitialCreate.cs file, which creates the database.

Badanie kontekstu zarejestrowane przy użyciu iniekcji zależnościExamine the context registered with dependency injection

Platforma ASP.NET Core został utworzony za pomocą wstrzykiwanie zależności (DI).ASP.NET Core is built with dependency injection (DI). Usługi (takie jak kontekst bazy danych programu EF Core) są rejestrowane przy użyciu DI podczas uruchamiania aplikacji.Services (such as the EF Core DB context) are registered with DI during application startup. Składniki, które wymagają tych usług (np. strony Razor) znajdują się tych usług za pomocą parametry konstruktora.Components that require these services (such as Razor Pages) are provided these services via constructor parameters. Kod konstruktora, który pobiera wystąpienia kontekstu bazy danych jest przedstawiony w dalszej części tego samouczka.The constructor code that gets a DB context instance is shown later in the tutorial.

Narzędzie do tworzenia szkieletów automatycznie tworzone kontekst bazy danych i jest on zarejestrowany za pomocą kontenera DI.The scaffolding tool automatically created a DB context and registered it with the DI container.

Sprawdź następujące Startup.ConfigureServices metody.Examine the following Startup.ConfigureServices method. Wyróżniony wiersz został dodany w procesie tworzenia szkieletu:The highlighted line was added by the scaffolder:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies 
        // is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddDbContext<MvcMovieContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
}

MvcMovieContext Współrzędne funkcji EF Core (tworzenia, odczytu, aktualizacji, usuwania, itp.) Movie modelu.The MvcMovieContext coordinates EF Core functionality (Create, Read, Update, Delete, etc.) for the Movie model. Kontekst danych (MvcMovieContext) jest tworzony na podstawie Microsoft.EntityFrameworkCore.DbContext.The data context (MvcMovieContext) is derived from Microsoft.EntityFrameworkCore.DbContext. Kontekst danych określa, które jednostki są uwzględnione w modelu danych:The data context specifies which entities are included in the data model:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace MvcMovie.Models
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
    }
}

Powyższy kod tworzy DbSet<film > właściwość zestawu jednostek.The preceding code creates a DbSet<Movie> property for the entity set. W terminologii programu Entity Framework zwykle zestaw jednostek odnosi się do tabeli bazy danych.In Entity Framework terminology, an entity set typically corresponds to a database table. Jednostki odnosi się do wiersza w tabeli.An entity corresponds to a row in the table.

Nazwa ciągu połączenia jest przekazywany do kontekstu przez wywołanie metody na DbContextOptions obiektu.The name of the connection string is passed in to the context by calling a method on a DbContextOptions object. Na potrzeby lokalnego programowania dla systemu konfiguracji platformy ASP.NET Core odczytuje parametry połączenia z appsettings.json pliku.For local development, the ASP.NET Core configuration system reads the connection string from the appsettings.json file.

Testowanie aplikacjiTest the app

  • Uruchom aplikację i dołączyć /Movies do adresu URL w przeglądarce (http://localhost:port/movies).Run the app and append /Movies to the URL in the browser (http://localhost:port/movies).

Jeśli pojawi się wyjątek bazy danych podobny do następującego:If you get a database exception similar to the following:

SqlException: Cannot open database "MvcMovieContext-GUID" requested by the login. The login failed.
Login failed for user 'User-name'.

Możesz pominąć krok migracji.You missed the migrations step.

  • Test Utwórz łącza.Test the Create link. Wprowadź i przesyłania danych.Enter and submit data.

    Uwaga

    Nie można wprowadzić dziesiętna przecinkami w Price pola.You may not be able to enter decimal commas in the Price field. Aby obsługiwać dotyczącą weryfikacji jQuery dla ustawień regionalnych innych niż angielski, które należy użyć przecinka (",") separator dziesiętny i formaty daty inne niż angielski, aplikacja musi globalizowana.To support jQuery validation for non-English locales that use a comma (",") for a decimal point and for non US-English date formats, the app must be globalized. Globalizacja instrukcje można znaleźć problem w usłudze GitHub.For globalization instructions, see this GitHub issue.

  • Test Edytuj, szczegóły, i Usuń łącza.Test the Edit, Details, and Delete links.

Sprawdź Startup klasy:Examine the Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies 
        // is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddDbContext<MvcMovieContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
}

Poprzedni kod wyróżniony pokazuje kontekst bazy danych filmów, które są dodawane do wstrzykiwanie zależności kontenera:The preceding highlighted code shows the movie database context being added to the Dependency Injection container:

  • services.AddDbContext<MvcMovieContext>(options => Określa bazę danych i parametry połączenia.services.AddDbContext<MvcMovieContext>(options => specifies the database to use and the connection string.
  • => jest operatora lambda=> is a lambda operator

Otwórz Controllers/MoviesController.cs plików i zbadaj konstruktora:Open the Controllers/MoviesController.cs file and examine the constructor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

    public MoviesController(MvcMovieContext context)
    {
        _context = context;
    }

Używa konstruktora wstrzykiwanie zależności iniekcję kontekst bazy danych (MvcMovieContext) do kontrolera.The constructor uses Dependency Injection to inject the database context (MvcMovieContext) into the controller. Kontekst bazy danych jest używany we wszystkich CRUD metodami w kontrolerze.The database context is used in each of the CRUD methods in the controller.

Silnie typizowane modeli i @model — słowo kluczoweStrongly typed models and the @model keyword

Wcześniej w tym samouczku pokazano, jak kontroler można przekazać dane i obiekty za pomocą widoku ViewData słownika.Earlier in this tutorial, you saw how a controller can pass data or objects to a view using the ViewData dictionary. ViewData Słownik jest to obiekt dynamiczny, która zapewnia wygodny sposób z późnym wiązaniem do przekazywania informacji do widoku.The ViewData dictionary is a dynamic object that provides a convenient late-bound way to pass information to a view.

MVC udostępnia również możliwość przekazywania silnie typizowanych obiektów modelu widoku.MVC also provides the ability to pass strongly typed model objects to a view. Silnie typizowane temu najlepszy czas kompilacji sprawdzania kodu.This strongly typed approach enables better compile time checking of your code. Mechanizm tworzenia szkieletów używane takie podejście (który jest przekazując silnie typizowany model) z MoviesController klasy i widoki utworzenia metod i widoków.The scaffolding mechanism used this approach (that is, passing a strongly typed model) with the MoviesController class and views when it created the methods and views.

Sprawdź wygenerowany Details method in Class metoda Controllers/MoviesController.cs pliku:Examine the generated Details method in the Controllers/MoviesController.cs file:

// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    if (movie == null)
    {
        return NotFound();
    }

    return View(movie);
}

id Parametr ogólnie jest przekazywany jako dane trasy.The id parameter is generally passed as route data. Na przykład https://localhost:5001/movies/details/1 ustawia:For example https://localhost:5001/movies/details/1 sets:

  • Kontroler do movies kontrolera (pierwszy segment adresu URL).The controller to the movies controller (the first URL segment).
  • Działanie details (drugi segment adresu URL).The action to details (the second URL segment).
  • Identyfikator do 1 (ostatni segment adresu URL).The id to 1 (the last URL segment).

Możesz również przekazać id przy użyciu zapytania następujący ciąg:You can also pass in the id with a query string as follows:

https://localhost:5001/movies/details?id=1

id Parametr jest zdefiniowany jako typu dopuszczającego wartość null (int?) w przypadku, gdy nie jest podana wartość Identyfikatora.The id parameter is defined as a nullable type (int?) in case an ID value isn't provided.

A wyrażenia lambda jest przekazywany do FirstOrDefaultAsync do wybrania jednostki filmu, które odpowiada wartości ciągu danych lub zapytanie trasy.A lambda expression is passed in to FirstOrDefaultAsync to select movie entities that match the route data or query string value.

var movie = await _context.Movie
    .FirstOrDefaultAsync(m => m.Id == id);

Jeśli film zostanie znaleziony, wystąpienie Movie modelu jest przekazywany do Details widoku:If a movie is found, an instance of the Movie model is passed to the Details view:

return View(movie);

Sprawdź zawartość Views/Movies/Details.cshtml pliku:Examine the contents of the Views/Movies/Details.cshtml file:

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

Jeśli dołączysz @model instrukcji w górnej części pliku widoku, można określić typu obiektu, który oczekuje, że widok.By including a @model statement at the top of the view file, you can specify the type of object that the view expects. Podczas tworzenia kontrolera filmu, następujące @model instrukcja została automatycznie dołączane u góry Details.cshtml pliku:When you created the movie controller, the following @model statement was automatically included at the top of the Details.cshtml file:

@model MvcMovie.Models.Movie

To @model dyrektywy umożliwia dostęp do filmów, która kontrolera przekazywane do widoku przy użyciu Model obiekt, który jest silnie typizowane.This @model directive allows you to access the movie that the controller passed to the view by using a Model object that's strongly typed. Na przykład w Details.cshtml widoku Kod przekazuje każdego pola film, aby DisplayNameFor i DisplayFor pomocników HTML za pomocą silnie typizowanej Model obiektu.For example, in the Details.cshtml view, the code passes each movie field to the DisplayNameFor and DisplayFor HTML Helpers with the strongly typed Model object. Create i Edit metody i widoki również przekazać Movie obiekt modelu.The Create and Edit methods and views also pass a Movie model object.

Sprawdź Index.cshtml widoku i Index metody w kontrolerze filmów.Examine the Index.cshtml view and the Index method in the Movies controller. Zwróć uwagę, jak kod tworzy List obiektu, kiedy wywoływanych przez nią View metody.Notice how the code creates a List object when it calls the View method. Kod przekazuje to Movies listy z Index metody akcji do widoku:The code passes this Movies list from the Index action method to the view:

// GET: Movies
public async Task<IActionResult> Index()
{
    return View(await _context.Movie.ToListAsync());
}

Podczas tworzenia kontrolera filmy tworzenia szkieletów automatycznie uwzględnione następujące @model instrukcji na górze Index.cshtml pliku:When you created the movies controller, scaffolding automatically included the following @model statement at the top of the Index.cshtml file:

@model IEnumerable<MvcMovie.Models.Movie>

@model Dyrektywy umożliwia dostęp do listy filmów, które kontrolera przekazywane do widoku przy użyciu Model obiekt, który jest silnie typizowane.The @model directive allows you to access the list of movies that the controller passed to the view by using a Model object that's strongly typed. Na przykład w Index.cshtml wyświetlić kod pętlę filmów z foreach instrukcji na silnie typizowaną Model obiektu:For example, in the Index.cshtml view, the code loops through the movies with a foreach statement over the strongly typed Model object:

@model IEnumerable<MvcMovie.Models.Movie>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@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>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Ponieważ Model obiektu zdecydowanie jest wpisane (jako IEnumerable<Movie> obiektu), każdy element w pętli jest wpisana jako Movie.Because the Model object is strongly typed (as an IEnumerable<Movie> object), each item in the loop is typed as Movie. Wśród innych korzyści oznacza to, uzyskasz czasie kompilacji sprawdzania kodu:Among other benefits, this means that you get compile time checking of the code:

Dodatkowe zasobyAdditional resources