Část 4: Přidání modelu do ASP.NET Core MVC

Rick Anderson a Jon P Smith.

V této části se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou "M odel" součástí aplikace M VC.

Tyto třídy modelu se používají Entity Framework Core (EF Core) pro práci s databází. EF Core je rozhraní orm (object-relational mapping), které zjednodušuje přístupový kód k datům, který musíte napsat.

Vytvořené modelové třídy se označuje jako *POCO _ classes od _*P**lain O ld C LR O přisluhoval. Třídy OBJEKTŮ POCO nejsou závislé na EF Core. Definují pouze vlastnosti dat, která se mají uložit do databáze.

V tomto kurzu se nejprve vytvoří modelové třídy a EF Core vytvoří databázi.

Přidání třídy datového modelu

Klikněte pravým tlačítkem na složku Models (Modely) > Add Class > (Přidat třídu). Pojmete soubor Movie.cs.

Aktualizujte soubor Models/Movie.cs následujícím kódem:

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

Třída obsahuje pole, které databáze vyžaduje Movie pro primární Id klíč.

Atribut DataType u určuje typ dat ( ReleaseDate Date ). Pomocí tohoto atributu:

  • Uživatel není nutné zadávat do pole datum informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

Poznámky k datům jsou probrány v pozdějším kurzu.

Přidání balíčků NuGet

V nabídce Nástroje vyberte NuGet Správce balíčků > Správce balíčků (PMC).

Nabídka PMC

V PMC spusťte následující příkaz:

Install-Package Microsoft.EntityFrameworkCore.Design

Předchozí příkazy přidávají:

  • Poskytovatel EF Core SQL Server. Balíček zprostředkovatele nainstaluje EF Core jako závislost.
  • Nástroje používané balíčky nainstalovanými automaticky v kroku generování uživatelského rozhraní dále v tomto kurzu.

Sestavte projekt jako kontrolu chyb kompilátoru.

Generování stránek filmů

Pomocí nástroje pro generování uživatelského rozhraní můžete vytvořit stránky , , a Create Read Update Delete (CRUD) pro model filmu.

V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers (Kontrolery) a vyberte Add > New Scaffolded Item (Přidat novou vysípravenou položku).

zobrazení výše uvedeného kroku

V dialogovém okně Přidat uživatelské rozhraní vyberte kontroler MVC se zobrazeními pomocí Entity Framework > Přidat.

Dialogové okno Přidat uživatelské rozhraní

Pomocí následujícího dialogového okna přidejte kontroler MVC Entity Framework zobrazení:

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcKu.Models).
  • V řádku Třídy kontextu dat vyberte + znaménko (plus).
    • V dialogovém okně Přidat kontext dat se vygeneruje název třídy MvcKu.Data.MvcContext.
    • Vyberte Přidat.
  • Views (Zobrazení) a Controller name (Název kontroleru): Podržte výchozí nastavení.
  • Vyberte Přidat.

Přidání kontextu dat – zachovat výchozí hodnoty

Generování uživatelského rozhraní aktualizuje následující:

  • Vloží požadované odkazy na balíček do souboru projektu Mvc Project.csproj.
  • Zaregistruje kontext databáze v Startup.ConfigureServices souboru Startup.cs.
  • Přidá do souboru připojovací řetězec appsettings.json databáze.

Generování uživatelského rozhraní vytvoří následující:

  • Kontroler filmů: Controllers/MoviesController.cs
  • Razor Zobrazení souborů pro vytváření, odstraňování, podrobnosti, úpravy a indexové stránky: Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/Mvc NěcoContext.cs

Automatické vytváření těchto souborů a aktualizací souborů se označuje jako generování uživatelského rozhraní.

Stránky s generováním uživatelského rozhraní zatím není možné použít, protože databáze neexistuje. Po spuštění aplikace a výběru odkazu Movie App (Filmová aplikace) se zobrazí chybová zpráva Movie (Filmová aplikace) a nelze otevřít databázi nebo žádnou takovou tabulku.

Počáteční migrace

K vytvoření EF Core použijte funkci migrace dat. Migrace jsou sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídala datovému modelu.

V nabídce Nástroje vyberte NuGet Správce balíčků > Správce balíčků Console .

V Správce balíčků (PMC) zadejte následující příkazy:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje soubor migrace Migrations/{timestamp}_InitialCreate.cs. Argumentem InitialCreate je název migrace. Můžete použít libovolný název, ale podle konvence se vybere název, který popisuje migraci. Vzhledem k tomu, že se jedná o první migraci, vygenerovaná třída obsahuje kód pro vytvoření schématu databáze. Schéma databáze je založené na modelu zadaném ve MvcMovieContext třídě .

  • Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí Up metodu v souboru Migrations/{time-stamp}_InitialCreate.cs, který vytvoří databázi.

Příkaz Update-Database vygeneruje následující upozornění:

Pro desetinný sloupec Price u entity typu Movie nebyl zadán žádný typ. To způsobí tiché zkrácení hodnot, pokud se nevejdou do výchozí přesnosti a škálování. Explicitně zadejte typ SQL serveru, který může pojmout všechny hodnoty, pomocí HasColumnType().

Předchozí upozornění ignorujte, v pozdějším kurzu je opravené.

Další informace o nástrojích PMC pro EF Core najdete v referenčních EF Core nástroje PMCv Visual Studio .

Otestování aplikace

Spusťte aplikaci a vyberte odkaz Movie App (Filmová aplikace).

Pokud dojde k výjimce podobné následující, možná jste v kroku migrace vynechali:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Poznámka

Je možné, že do pole nebudete moct zadat desetinné Price čárky. Pro podporu ověřování jQuery pro jiná než anglické národní prostředí, která používají čárku (",") pro desetinnou čárku a pro jiné než US-English data, musí být aplikace globalizovaná. Pokyny k globalizaci najdete v tomto GitHub problému.

Prozkoumání třídy a registrace kontextu vygenerované databáze

Při EF Core se přístup k datům provádí pomocí modelu. Model je tvořen třídami entit a objektem kontextu, který představuje relaci s databází. Kontextový objekt umožňuje dotazování a ukládání dat. Kontext databáze je odvozen z Microsoft.EntityFrameworkCore.DbContext a určuje entity, které se mají zahrnout do datového modelu.

Generování uživatelského rozhraní vytvoří třídu kontextu databáze Data/MvcFoldContext.cs:

using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

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

        public DbSet<Movie> Movie { get; set; }
    }
}

Předchozí kód vytvoří vlastnost DbSet, <Movie> která představuje filmy v databázi.

ASP.NET Core je sestaven pomocí injektáže závislostí (DI). Služby, jako je například kontext databáze, musí být zaregistrované u IN v Startup . Komponenty, které vyžadují tyto služby, se poskytují prostřednictvím parametrů konstruktoru.

V souboru Controllers/MoviesController.cs používá konstruktor injektáž závislostí k vložení kontextu databáze MvcMovieContext do kontroleru. Kontext databáze se používá v každé metodě CRUD v kontroleru.

Při generování uživatelského rozhraní se v vygeneroval následující zvýrazněný Startup.ConfigureServices kód:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

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

Konfigurační ASP.NET Core systému načte připojovací řetězec databáze MvcContext.

Prozkoumání vygenerované databázového připojovacího řetězce

Generování uživatelského rozhraní přidalo do souboru připojovací appsettings.json řetězec:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

V případě místního vývoje ASP.NET Core systém načte ConnectionString klíč ze souboru appsettings.json .

Třída InitialCreate

Prozkoumejte soubor migrace Migrations/{timestamp}_InitialCreate.cs:

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movie",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movie", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movie");
    }
}

V předchozím kódu:

  • InitialCreate.Up vytvoří tabulku Movie (Film) a Id nakonfiguruje se jako primární klíč.
  • InitialCreate.Down vrátí změny schématu provedené Up migrací.

Injektáž závislostí v kontroleru

Otevřete soubor Controllers/MoviesController.cs a prozkoumejte konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

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

Konstruktor používá injektáž závislostí k vložení kontextu databáze ( MvcMovieContext ) do kontroleru. Kontext databáze se používá v každé metodě CRUD v kontroleru.

Otestujte stránku Vytvořit. Zadejte a odešlete data.

Otestujte stránky Upravit, Podrobnosti a Odstranit.

Modely se silnými typy a @model direktiva

Dříve v tomto kurzu jste viděli, jak může kontroler předávat data nebo objekty do zobrazení pomocí ViewData slovníku . Slovník je dynamický objekt, který poskytuje pohodlný pozdní způsob předání ViewData informací do zobrazení.

MVC poskytuje možnost předat do zobrazení objekty modelu silného typu. Tento přístup se silnými typy umožňuje kontrolu kódu v době kompilace. Mechanismus generování předal model silného typu ve třídě a MoviesController zobrazení.

Prozkoumejte vygenerované Details metody v souboru Controllers/MoviesController.cs:

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

Parametr id se obvykle předává jako data trasy. Například https://localhost:5001/movies/details/1 nastaví:

  • Kontroler do movies kontroleru, první segment adresy URL.
  • Akce na details , druhý segment adresy URL.
  • Na id 1, poslední segment adresy URL.

Parametr id se může předat s řetězcem dotazu jako v následujícím příkladu:

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

Parametr id je definován jako typ s možnou hodnotou null ( ) v případech, kdy hodnota není int? id zadána.

Výraz lambda se předá metodě pro výběr entit filmů, které odpovídají datům trasy FirstOrDefaultAsync nebo řetězcové hodnotě dotazu.

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

Pokud je nalezen film, instance modelu se Movie předá do Details zobrazení:

return View(movie);

Prozkoumejte obsah souboru Views/Movies/Details.cshtml:

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

Příkaz @model v horní části souboru zobrazení určuje typ objektu, který zobrazení očekává. Při vytvoření filmového kontroleru byl zahrnut @model následující příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal zobrazení. Objekt Model je silného typu. Například v zobrazení Details.cshtml kód předává každé pole filmu do pomocníků a HTML s objektem DisplayNameFor DisplayFor silného Model typu. Metody Create Edit a a také předá Movie objekt modelu.

Prozkoumejte zobrazení Index.cshtml a Index metodu v kontroleru Movies. Všimněte si, jak kód List vytvoří objekt při volání metody View . Kód předá tento Movies seznam z metody akce do Index zobrazení:

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

Při vytvoření kontroleru filmů zahrnula generování uživatelského rozhraní na začátek souboru @model Index.cshtml následující příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva umožňuje přístup k seznamu filmů, které kontroler předal zobrazení pomocí objektu @model Model silného typu. Například v zobrazení Index.cshtml kód prochází filmy pomocí příkazu nad objektem foreach silného Model typu:

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

Vzhledem k Model tomu, že objekt je silného typu jako objekt, je každá položka ve smyčce IEnumerable<Movie> typována jako Movie . Kromě jiných výhod kompilátor ověřuje typy používané v kódu.

SQL Protokolování Entity Framework Core

Konfiguraci protokolování obvykle poskytuje část Logging nastavení aplikace. {Environment} Soubory .json. Pokud chcete SQL příkazy, "Microsoft.EntityFrameworkCore.Database.Command": "Information" přidejte je doappsettings.Development.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
     ,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
    }
  },
  "AllowedHosts": "*"
}

V předchozím kódu JSON se SQL příkazové řádky a v okně výstupu Visual Studio kódu.

Další informace najdete v tématu a Protokolování v .NET Core a ASP.NET Core o tomto GitHub.

Další zdroje informací

Přidání třídy datového modelu

Klikněte pravým tlačítkem na složku Models (Modely) > Add Class > (Přidat třídu). Pojmete soubor Movie.cs.

Aktualizujte soubor Models/Movie.cs následujícím kódem:

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

Třída obsahuje pole, které databáze vyžaduje Movie pro primární Id klíč.

Atribut DataType u určuje typ dat ( ReleaseDate Date ). Pomocí tohoto atributu:

  • Uživatel není nutné zadávat do pole datum informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

Poznámky k datům jsou probrány v pozdějším kurzu.

Přidání balíčků NuGet

V nabídce Nástroje vyberte NuGet Správce balíčků > Správce balíčků Console (PMC).

Nabídka PMC

V PMC spusťte následující příkaz:

Install-Package Microsoft.EntityFrameworkCore.Design

Předchozí příkazy přidávají:

  • Poskytovatel EF Core SQL Server. Balíček zprostředkovatele nainstaluje EF Core jako závislost.
  • Nástroje používané balíčky nainstalovanými automaticky v kroku generování uživatelského rozhraní dále v tomto kurzu.

Sestavte projekt jako kontrolu chyb kompilátoru.

Generování stránek filmů

Pomocí nástroje pro generování uživatelského rozhraní můžete vytvořit stránky , , a Create Read Update Delete (CRUD) pro model filmu.

V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers (Kontrolery) a vyberte Add > New Scaffolded Item (Přidat novou vysípravenou položku).

zobrazení výše uvedeného kroku

V dialogovém okně Přidat uživatelské rozhraní vyberte kontroler MVC se zobrazeními pomocí Entity Framework > Přidat.

Dialogové okno Přidat uživatelské rozhraní

Dokončete dialogové okno Přidat kontroler MVC se zobrazeními Entity Framework dialogového okna:

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcKu.Models).
  • V řádku Třídy kontextu dat vyberte + znaménko (plus).
    • V dialogovém okně Přidat kontext dat se vygeneruje název třídy MvcKu.Data.MvcContext.
    • Vyberte Přidat.
  • Views (Zobrazení) a Controller name (Název kontroleru): Podržte výchozí nastavení.
  • Vyberte Přidat.

Přidání kontextu dat – zachovat výchozí hodnoty

Generování uživatelského rozhraní aktualizuje následující:

  • Vloží požadované odkazy na balíček do souboru projektu Mvc Project.csproj.
  • Zaregistruje kontext databáze v Startup.ConfigureServices souboru Startup.cs.
  • Přidá do souboru připojovací řetězec appsettings.json databáze.

Generování uživatelského rozhraní vytvoří následující:

  • Kontroler filmů: Controllers/MoviesController.cs
  • Razor Zobrazení souborů pro vytváření, odstraňování, podrobnosti, úpravy a indexové stránky: Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/Mvc NěcoContext.cs

Automatické vytváření těchto souborů a aktualizací souborů se označuje jako generování uživatelského rozhraní.

Stránky s generováním uživatelského rozhraní zatím není možné použít, protože databáze neexistuje. Po spuštění aplikace a výběru odkazu Movie App (Filmová aplikace) se zobrazí chybová zpráva Movie (Filmová aplikace) a nelze otevřít databázi nebo žádnou takovou tabulku.

Počáteční migrace

K vytvoření EF Core použijte funkci migrace dat. Migrace jsou sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídala datovému modelu.

v nabídce nástroje vyberte NuGet Správce balíčků > Správce balíčků konzole .

v konzole Správce balíčků (PMC) zadejte následující příkazy:

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje migrační soubor _InitialCreate. cs migrace/{timestamp} . InitialCreateArgument je název migrace. Můžete použít libovolný název, ale podle konvence je vybraný název, který popisuje migraci. Vzhledem k tomu, že se jedná o první migraci, vygenerovaná třída obsahuje kód pro vytvoření schématu databáze. Schéma databáze je založené na modelu určeném ve MvcMovieContext třídě.

  • Update-Database: Aktualizuje databázi na nejnovější migraci, která vytvořila předchozí příkaz. Tento příkaz spustí Up metodu v souboru migrations/{Time-razítk} _InitialCreate. cs , ve kterém se vytvoří databáze.

Update-DatabasePříkaz vygeneruje následující upozornění:

Pro desetinný sloupec ' Price ' pro typ entity ' film ' nebyl zadán žádný typ. To způsobí, že se hodnoty tiše zkrátí, pokud se nevejdou do výchozí přesnosti a rozsahu. explicitně zadejte typ sloupce SQL serveru, který může obsahovat všechny hodnoty pomocí ' HasColumnType () '.

Ignorovat předchozí upozornění, je opraveno v pozdějším kurzu.

Další informace o nástrojích PMC pro EF Core najdete v referenčních EF Core nástroje PMCv Visual Studio .

Otestování aplikace

Spusťte aplikaci a vyberte odkaz filmové aplikace .

Pokud se zobrazí výjimka podobná následující, možná jste nenalezli Krok migrace:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Poznámka

V poli možná nebudete moct zadat desítkové čárky Price . Aby bylo možné podporovat ověřování jQuery pro jiné než anglické národní prostředí, které používá čárku (",") pro desetinnou čárku a pro neUS-English formáty data, musí být aplikace globální. pokyny k globalizaci najdete v tomto GitHub problému.

Prověřte vygenerovanou třídu kontextu databáze a její registraci.

Při použití EF Core se přístup k datům provádí pomocí modelu. Model je tvořen třídami entit a objektem kontextu, který představuje relaci s databází. Kontextový objekt umožňuje dotazování a ukládání dat. Kontext databáze je odvozen od třídy Microsoft. EntityFrameworkCore. DbContext a určuje entity, které mají být zahrnuty do datového modelu.

Generování uživatelského rozhraní vytvoří třídu kontextu databáze data/MvcMovieContext. cs :

using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

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

        public DbSet<Movie> Movie { get; set; }
    }
}

Předchozí kód vytvoří vlastnost negenerickými <Movie> , která představuje filmy v databázi.

ASP.NET Core je sestaven s vkládáním závislostí (DI). Služby, jako je například kontext databáze, musí být registrovány v DI v Startup . Komponenty, které vyžadují tyto služby, jsou poskytovány prostřednictvím parametrů konstruktoru.

V souboru Controllers/MoviesController. cs konstruktor používá vkládání závislostí pro vložení MvcMovieContext kontextu databáze do kontroleru. Kontext databáze se používá v každé metodě CRUD v kontroleru.

Generování uživatelského rozhraní vygenerovalo následující zvýrazněný kód v Startup.ConfigureServices :

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

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

konfigurační systém ASP.NET Core přečte připojovací řetězec databáze "MvcMovieContext".

Prověřte vygenerovaný připojovací řetězec databáze.

Generování uživatelského rozhraní přidaného připojovacího řetězce do appsettings.json souboru:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

pro místní vývoj ASP.NET Core konfigurační systém přečte ConnectionString klíč ze appsettings.json souboru.

InitialCreateTřída

Projděte si soubor migrace /{timestamp} _InitialCreate. cs :

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movie",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movie", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movie");
    }
}

V předchozím kódu:

  • InitialCreate.Up Vytvoří tabulku filmů a nakonfiguruje Id ji jako primární klíč.
  • InitialCreate.Down Vrátí změny schématu provedené Up migrací.

Vkládání závislostí v kontroleru

Otevřete soubor Controllers/MoviesController. cs a prověřte konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

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

Konstruktor používá vkládání závislostí pro vložení kontextu databáze ( MvcMovieContext ) do kontroleru. Kontext databáze se používá v každé metodě CRUD v kontroleru.

Otestujte stránku vytvořit . Zadejte a odešlete data.

Otestujte stránky Upravit, Podrobnosti a Odstranit .

Modely silného typu a @model direktiva

Dříve v tomto kurzu jste viděli, jak může řadič předat data nebo objekty do zobrazení pomocí ViewData slovníku. ViewDataSlovník je dynamický objekt, který poskytuje pohodlný způsob, jak předat informace do zobrazení.

MVC nabízí možnost předat objekty modelu silného typu do zobrazení. Tento přístup se silnými typy umožňuje kompilovat kontrolu kódu při kompilaci. Mechanismus generování uživatelského rozhraní prošel modelem silného typu ve MoviesController třídě a zobrazeních.

Prověřte vygenerovanou Details metodu v souboru Controllers/MoviesController. cs :

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

idParametr je obvykle předán jako data směrování. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler do movies kontroleru, první segment adresy URL.
  • Akce, na kterou details druhý segment adresy URL.
  • Na id 1, poslední segment adresy URL.

idLze předat pomocí řetězce dotazu, jak je uvedeno v následujícím příkladu:

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

idParametr je definován jako typ s možnou hodnotou null ( int? ) v případě, že id není zadána hodnota.

Výraz lambda je předán FirstOrDefaultAsync metodě pro výběr entit videa, které odpovídají datům směrování nebo hodnotě řetězce dotazu.

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

Pokud se najde film, Movie do zobrazení se předává instance modelu Details :

return View(movie);

Projděte si obsah souboru views/video/details. cshtml :

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

@modelPříkaz v horní části souboru zobrazení určuje typ objektu, který zobrazení očekává. Po vytvoření kontroleru filmů @model byl zahrnut následující příkaz:

@model MvcMovie.Models.Movie

Tato @model Direktiva umožňuje přístup k videu, který kontroler předali do zobrazení. ModelObjekt je silného typu. Například v zobrazení Details. cshtml kód předá každé pole videa do DisplayNameFor DisplayFor pomocníků HTML a s objektem silného typu Model . CreateMetody a Edit zobrazení také předají Movie objekt modelu.

Prohlédněte si zobrazení index. cshtml a Index metodu v řadiči filmů. Všimněte si, jak kód List při volání metody vytvoří objekt View . Kód předá tento Movies seznam z Index metody Action do zobrazení:

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

Po vytvoření kontroleru filmů zahrnuje generování uživatelského rozhraní do @model horní části souboru index. cshtml tento příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

@modelDirektiva umožňuje přístup k seznamu filmů, které kontroler předává do zobrazení pomocí Model objektu se silným typem. Například v zobrazení index. cshtml přechází kód přes filmy pomocí foreach příkazu nad objektem silného typu Model :

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

Vzhledem k tomu Model , že objekt je silně typový jako IEnumerable<Movie> objekt, každá položka ve smyčce je zapsána jako Movie . Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

SQL Protokolování Entity Framework Core

Konfiguraci protokolování obvykle poskytuje část Logging nastavení aplikace. {Environment} Soubory .json. Pokud chcete SQL příkazy, "Microsoft.EntityFrameworkCore.Database.Command": "Information" přidejte je doappsettings.Development.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
     ,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
    }
  },
  "AllowedHosts": "*"
}

V předchozím kódu JSON se SQL příkazové řádky a v okně výstupu Visual Studio kódu.

Další informace najdete v tématu a Protokolování v .NET Core a ASP.NET Core o tomto GitHub.

Další zdroje informací

Přidat třídu datového modelu

Klikněte pravým tlačítkem na složku modely > Přidat > třídu. Pojmenujte soubor video. cs.

Aktualizujte soubor Movie. cs pomocí následujícího kódu:

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

MovieTřída obsahuje Id pole, které je vyžadováno databází pro primární klíč.

DataTypeAtribut v ReleaseDate Určuje typ dat ( Date ). S tímto atributem:

  • Uživatel není požádán o zadání informací o čase do pole datum.
  • Zobrazí se pouze datum, nejedná se o informace o čase.

V pozdějším kurzu jsou uvedena tato Anotace .

Přidání balíčků NuGet

v nabídce nástroje vyberte NuGet Správce balíčků > Správce balíčků konzole (PMC).

PMC – nabídka

V PMC spusťte následující příkaz:

Install-Package Microsoft.EntityFrameworkCore.SqlServer

předchozí příkaz přidá poskytovatele EF Core SQL Server. Balíček Provider nainstaluje balíček EF Core jako závislost. Další balíčky jsou automaticky nainstalovány v kroku generování uživatelského rozhraní později v tomto kurzu.

Vytvoření třídy kontextu databáze

Třída kontextu databáze je nutná ke koordinaci funkcí EF Core (vytvoření, čtení, aktualizace, odstranění) Movie modelu. Kontext databáze je odvozen od třídy Microsoft. EntityFrameworkCore. DbContext a určuje entity, které mají být zahrnuty do datového modelu.

Vytvořte složku dat .

Přidejte soubor data/MvcMovieContext. cs s následujícím kódem:

using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;

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

        public DbSet<Movie> Movie { get; set; }
    }
}

Předchozí kód vytvoří vlastnost negenerickými <Movie> pro sadu entit. V Entity Framework terminologii sada entit obvykle odpovídá databázové tabulce. Entita odpovídá řádku v tabulce.

Registrace kontextu databáze

ASP.NET Core je sestaven s vkládáním závislostí (DI). Služby (například kontext EF Core DB) musí být při spuštění aplikace zaregistrované v DI. Komponenty, které vyžadují tyto služby (například Razor stránky), jsou poskytovány prostřednictvím parametrů konstruktoru. Kód konstruktoru, který získá instanci kontextu databáze, je uveden dále v tomto kurzu. V této části zaregistrujete kontext databáze pomocí kontejneru DI.

Do horní části using Startup. cs přidejte následující příkazy:

using MvcMovie.Data;
using Microsoft.EntityFrameworkCore;

Do následujícího pole přidejte následující zvýrazněný kód Startup.ConfigureServices :

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

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

Název připojovacího řetězce je předán do kontextu voláním metody v objektu DbContextOptions . pro místní vývoj načítá konfigurační systém ASP.NET Core připojovací řetězec ze appsettings.json souboru.

Prověřte připojovací řetězec databáze.

Přidat připojovací řetězec do appsettings.json souboru:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmového uživatelského rozhraní

Použijte nástroj pro generování uživatelského rozhraní k vytvoření stránek pro vytváření, čtení, aktualizaci a odstranění (CRUD) pro model filmu.

V Průzkumník řešení klikněte pravým tlačítkem myši na složku Controllers > přidat > novou vygenerované položky.

zobrazení výše uvedeného kroku

V dialogovém okně Přidat generování uživatelského rozhraní vyberte kontroler MVC se zobrazeními a pomocí Entity Framework > přidat.

Dialogové okno Přidat generování uživatelského rozhraní

Dokončete dialog Přidat řadič :

  • Třída modelu: video (MvcMovie. Models)
  • Třída kontextu dat: MvcMovieContext (MvcMovie. data)

Přidat kontext dat

  • Zobrazení: Ponechte výchozí hodnotu u každé zaškrtnuté možnosti.
  • Název kontroleru: Zachovat výchozí MoviesController
  • Vyberte Přidat.

Visual Studio vytvoří:

  • Řadič filmů (Controllers/MoviesController. cs)
  • Razor zobrazení souborů pro stránky vytvořit, odstranit, podrobnosti, upravit a index (zobrazení/filmy/ * . cshtml)

Automatické vytváření těchto souborů se říká generování uživatelského rozhraní.

Vygenerované stránky nemůžete zatím použít, protože databáze neexistuje. Pokud aplikaci spouštíte a kliknete na odkaz filmové aplikace , nemůžete otevřít databázi nebo žádnou takovou tabulku: chybová zpráva videa.

Počáteční migrace

K vytvoření databáze použijte funkci migrace EF Core. Migrace je sada nástrojů, která umožňuje vytvořit a aktualizovat databázi tak, aby odpovídala vašemu datovému modelu.

v nabídce nástroje vyberte NuGet Správce balíčků > Správce balíčků konzole (PMC).

Do PMC zadejte následující příkazy:

Add-Migration InitialCreate
Update-Database
  • Add-Migration InitialCreate: Vygeneruje migrační soubor _InitialCreate. cs migrace/{timestamp} . InitialCreateArgument je název migrace. Můžete použít libovolný název, ale podle konvence je vybraný název, který popisuje migraci. Vzhledem k tomu, že se jedná o první migraci, vygenerovaná třída obsahuje kód pro vytvoření schématu databáze. Schéma databáze je založené na modelu určeném ve MvcMovieContext třídě.

  • Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí Up metodu v souboru Migrations/{time-stamp}_InitialCreate.cs, který vytvoří databázi.

    Příkaz pro aktualizaci databáze vygeneruje následující upozornění:

    Pro desetinný sloupec Price u entity typu Movie nebyl zadán žádný typ. To způsobí tiché zkrácení hodnot, pokud se nevejdou do výchozí přesnosti a škálování. Explicitně zadejte typ SQL serveru, který může pojmout všechny hodnoty, pomocí HasColumnType().

    Toto upozornění můžete ignorovat, v pozdějším kurzu bude opravené.

Další informace o nástrojích PMC pro EF Core najdete v referenčních EF Core nástroje PMCv Visual Studio .

Třída InitialCreate

Prozkoumejte soubor migrace Migrations/{timestamp}_InitialCreate.cs:

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movie",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", 
                                 SqlServerValueGenerationStrategy.IdentityColumn),
                Title = table.Column<string>(nullable: true),
                ReleaseDate = table.Column<DateTime>(nullable: false),
                Genre = table.Column<string>(nullable: true),
                Price = table.Column<decimal>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movie", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movie");
    }
}

Metoda Up vytvoří tabulku Movie a nakonfiguruje Id jako primární klíč. Metoda Down vrátí změny schématu provedené migrací. Up

Otestování aplikace

  • Spusťte aplikaci a klikněte na odkaz Movie App (Filmová aplikace).

    Pokud dojde k výjimce podobné jedné z následujících:

SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.

Pravděpodobně jste vynechali krok migrace.

  • Otestujte stránku Vytvořit. Zadejte a odešlete data.

    Poznámka

    Je možné, že do pole nebudete moct zadat desetinné Price čárky. Pro podporu ověřování jQuery pro jiná než anglické národní prostředí, která používají čárku (",") pro desetinnou čárku a pro jiné než US-English data, musí být aplikace globalizovaná. Pokyny k globalizaci najdete v tomto GitHub problému.

  • Otestujte stránky Upravit, Podrobnosti a Odstranit.

Injektáž závislostí v kontroleru

Otevřete soubor Controllers/MoviesController.cs a prozkoumejte konstruktor:

public class MoviesController : Controller
{
    private readonly MvcMovieContext _context;

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

Konstruktor používá injektáž závislostí k vložení kontextu databáze ( MvcMovieContext ) do kontroleru. Kontext databáze se používá v každé metodě CRUD v kontroleru.

Modely se silnými typy a klíčové @model slovo

Dříve v tomto kurzu jste viděli, jak může kontroler předávat data nebo objekty do zobrazení pomocí ViewData slovníku . Slovník je dynamický objekt, který poskytuje pohodlný pozdní způsob předání ViewData informací do zobrazení.

MVC také umožňuje předat do zobrazení objekty modelu silného typu. Tento přístup se silnými typy umožňuje kontrolu kódu v době kompilace. Mechanismus generování použil tento přístup (to znamená předání modelu silného typu) s třídou a MoviesController zobrazeními.

Prozkoumejte vygenerované Details metody v souboru Controllers/MoviesController.cs:

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

Parametr id se obvykle předává jako data trasy. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler movies kontroleru (první segment adresy URL).
  • Akce na details (druhý segment adresy URL).
  • ID na 1 (poslední segment adresy URL).

Můžete také předat s id řetězcem dotazu následujícím způsobem:

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

Parametr id je definován jako typ s možnou hodnotou null ( ) v případě, že není int? zadána hodnota ID.

Výraz lambda se předá do pro výběr entit filmů, které odpovídají datům FirstOrDefaultAsync trasy nebo řetězcové hodnotě dotazu.

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

Pokud je nalezen film, instance modelu se Movie předá do Details zobrazení:

return View(movie);

Prozkoumejte obsah souboru Views/Movies/Details.cshtml:

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

Příkaz @model v horní části souboru zobrazení určuje typ objektu, který zobrazení očekává. Při vytvoření filmového kontroleru byl zahrnut @model následující příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal zobrazení. Objekt Model je silného typu. Například v zobrazení Details.cshtml kód předává každé pole filmu do pomocníků a HTML s objektem DisplayNameFor DisplayFor silného Model typu. Metody Create Edit a a také předá Movie objekt modelu.

Prozkoumejte zobrazení Index.cshtml a Index metodu v kontroleru Movies. Všimněte si, jak kód List vytvoří objekt při volání metody View . Kód předá tento Movies seznam z metody akce do Index zobrazení:

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

Při vytvoření kontroleru filmů zahrnula generování uživatelského rozhraní na začátek souboru @model Index.cshtml následující příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva umožňuje přístup k seznamu filmů, které kontroler předal zobrazení, pomocí objektu @model Model silného typu. Například v zobrazení Index.cshtml kód prochází filmy pomocí příkazu nad objektem foreach silného Model typu:

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

Vzhledem k Model tomu, že objekt je silného typu (jako objekt), je každá položka ve smyčce IEnumerable<Movie> typována jako Movie . Mimo jiné to znamená, že získáte kontrolu času kompilace kódu.

Další zdroje informací