Sdílet prostřednictvím


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

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Rick Anderson a Jon P Smith.

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

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

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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

  • Uživatel nemusí do pole kalendářního data zadávat informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

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

Otazník po string značí, že vlastnost je nullable. Další informace naleznete v tématu Odkazové typy s možnou hodnotou Null.

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

Visual Studio automaticky nainstaluje požadované balíčky.

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery a vyberte Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

V dialogovém okně Přidat novou vygenerovanou položku :

  • V levém podokně vyberte Nainstalované>společné>MVC.
  • Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
  • Vyberte Přidat.

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

Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcMovie.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 MvcMovie.Data.MvcMovieContext .
    • Vyberte Přidat.
  • V rozevíracím seznamu Poskytovatel databáze vyberte SQL Server.
  • Zobrazení a název kontroleru: Ponechte výchozí nastavení.
  • Vyberte Přidat.

Zachování výchozích hodnot kontextu přidání dat

Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.

Generování uživatelského rozhraní přidá následující balíčky:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

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

  • Ovladač filmů: Controllers/MoviesController.cs
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index : Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/MvcMovieContext.cs

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

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

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

Vygenerované stránky se zatím nedají použít, protože databáze neexistuje. Spuštění aplikace a výběr odkazu Movie App má za následek nemožnost otevřít databázi nebo žádnou takovou tabulku: Chybová zpráva Film .

Sestavte aplikaci, abyste ověřili, že nedošlo k žádným chybám.

Počáteční migrace

EF CoreK vytvoření databáze použijte funkci Migrace. Migrace je sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídaly datovému modelu.

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

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

Add-Migration InitialCreate

  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

Zobrazí se následující upozornění, které je vyřešeno v pozdějším kroku:

Nebyl zadán žádný typ úložiště pro desetinnou vlastnost Price u typu entity Movie. To způsobí, že se hodnoty bezobslužně zkrátí, pokud se nevejdou do výchozí přesnosti a měřítka. Explicitně zadejte typ sloupce SERVERU SQL, který může obsahovat všechny hodnoty v onModelCreating pomocí HasColumnType, určit přesnost a škálování pomocí HasPrecision nebo nakonfigurovat převaděč hodnot pomocí HasConversion.

V PMC zadejte následující příkaz:

Update-Database

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

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě Visual Studio.

Otestování aplikace

Spusťte aplikaci a vyberte odkaz Filmová aplikace .

Pokud se zobrazí výjimka podobná následující, pravděpodobně jste příkaz v kroku migrace vynechaliUpdate-Database:

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

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

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

Pomocí EF Coremodelu se provádí přístup k datům. Model se skládá z tříd entit a kontextového objektu, 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ří Data/MvcMovieContext.cs třídu kontextu databáze:

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

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

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

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

Injektáž závislostí

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované v adresáři DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.

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

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

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext") ?? throw new InvalidOperationException("Connection string 'MvcMovieContext' not found.")));

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

Prozkoumání vygenerované databáze připojovací řetězec

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

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-4ebefa10-de29-4dea-b2ad-8a8dc6bcf374;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

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

Třída InitialCreate

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

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    /// <inheritdoc />
    public partial class InitialCreate : Migration
    {
        /// <inheritdoc />
        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);
                });
        }

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

V předchozím kódu:

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

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z 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 direktiva @model

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

MVC poskytuje možnost předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní předal model silného MoviesController typu ve třídě a zobrazeních.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler na movies kontroler, první segment adresy URL.
  • Akce na details, druhý segment adresy URL.
  • Hodnota id 1, poslední segment adresy URL.

id se předat pomocí řetězce dotazu, jak je znázorněno 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 (int?) v případech, kdy není zadána id hodnota.

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

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Kód vrátí podrobnosti o problému, pokud Movie je vlastnost kontextu dat null.

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí objektu silného Model typu. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silně zadán jako IEnumerable<Movie> objekt, každá položka ve smyčce je zadána jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

Další materiály

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

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

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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

  • Uživatel nemusí do pole kalendářního data zadávat informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

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

Otazník po string značí, že vlastnost je nullable. Další informace naleznete v tématu Odkazové typy s možnou hodnotou Null.

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

Visual Studio automaticky nainstaluje požadované balíčky.

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery a vyberte Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

V dialogovém okně Přidat novou vygenerovanou položku :

  • V levém podokně vyberte Nainstalované>společné>MVC.
  • Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
  • Vyberte Přidat.

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

Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcMovie.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 MvcMovie.Data.MvcMovieContext .
    • Vyberte Přidat.
  • V rozevíracím seznamu Poskytovatel databáze vyberte SQL Server.
  • Zobrazení a název kontroleru: Ponechte výchozí nastavení.
  • Vyberte Přidat.

Zachování výchozích hodnot kontextu přidání dat

Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.

Generování uživatelského rozhraní přidá následující balíčky:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

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

  • Ovladač filmů: Controllers/MoviesController.cs
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index : Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/MvcMovieContext.cs

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

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

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

Vygenerované stránky se zatím nedají použít, protože databáze neexistuje. Spuštění aplikace a výběr odkazu Movie App má za následek nemožnost otevřít databázi nebo žádnou takovou tabulku: Chybová zpráva Film .

Sestavte aplikaci, abyste ověřili, že nedošlo k žádným chybám.

Počáteční migrace

EF CoreK vytvoření databáze použijte funkci Migrace. Migrace je sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídaly datovému modelu.

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

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

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

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

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

Nebyl zadán žádný typ úložiště pro desetinnou vlastnost Price u typu entity Movie. To způsobí, že se hodnoty bezobslužně zkrátí, pokud se nevejdou do výchozí přesnosti a měřítka. Explicitně zadejte typ sloupce SERVERU SQL, který může obsahovat všechny hodnoty v onModelCreating pomocí HasColumnType, určit přesnost a škálování pomocí HasPrecision nebo nakonfigurovat převaděč hodnot pomocí HasConversion.

Předchozí upozornění ignorujte, opravili jsme ho v pozdějším kurzu.

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě Visual Studio.

Otestování aplikace

Spusťte aplikaci a vyberte odkaz Filmová aplikace .

Pokud se zobrazí výjimka podobná následující, pravděpodobně jste příkaz v kroku migrace vynechaliUpdate-Database:

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

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

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

Pomocí EF Coremodelu se provádí přístup k datům. Model se skládá z tříd entit a kontextového objektu, 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ří Data/MvcMovieContext.cs třídu kontextu databáze:

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

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

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

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

Injektáž závislostí

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované v adresáři DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.

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

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

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

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

Prozkoumání vygenerované databáze připojovací řetězec

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

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
  }
}

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

Třída InitialCreate

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

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    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 a nakonfiguruje Id jako primární klíč.
  • InitialCreate.Down vrátí změny schématu provedené migrací Up .

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z 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 direktiva @model

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

MVC poskytuje možnost předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní předal model silného MoviesController typu ve třídě a zobrazeních.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler na movies kontroler, první segment adresy URL.
  • Akce na details, druhý segment adresy URL.
  • Hodnota id 1, poslední segment adresy URL.

id se předat pomocí řetězce dotazu, jak je znázorněno 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 (int?) v případech, kdy není zadána id hodnota.

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

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Kód vrátí podrobnosti o problému, pokud Movie je vlastnost kontextu dat null.

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí objektu silného Model typu. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silně zadán jako IEnumerable<Movie> objekt, každá položka ve smyčce je zadána jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

Další materiály

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

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

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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

  • Uživatel nemusí do pole kalendářního data zadávat informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

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

Otazník po string značí, že vlastnost je nullable. Další informace naleznete v tématu Odkazové typy s možnou hodnotou Null.

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

Visual Studio automaticky nainstaluje požadované balíčky.

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery a vyberte Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

V dialogovém okně Přidat novou vygenerovanou položku :

  • V levém podokně vyberte Nainstalované>společné>MVC.
  • Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
  • Vyberte Přidat.

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

Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcMovie.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 MvcMovie.Data.MvcMovieContext .
    • Vyberte Přidat.
  • V rozevíracím seznamu Poskytovatel databáze vyberte SQL Server.
  • Zobrazení a název kontroleru: Ponechte výchozí nastavení.
  • Vyberte Přidat.

Zachování výchozích hodnot kontextu přidání dat Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.

Generování uživatelského rozhraní přidá následující balíčky:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.VisualStudio.Web.CodeGeneration.Design

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

  • Ovladač filmů: Controllers/MoviesController.cs
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index : Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/MvcMovieContext.cs

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

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

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

Vygenerované stránky se zatím nedají použít, protože databáze neexistuje. Spuštění aplikace a výběr odkazu Movie App má za následek nemožnost otevřít databázi nebo žádnou takovou tabulku: Chybová zpráva Film .

Sestavte aplikaci, abyste ověřili, že nedošlo k žádným chybám.

Počáteční migrace

EF CoreK vytvoření databáze použijte funkci Migrace. Migrace je sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídaly datovému modelu.

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

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

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

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

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

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

Předchozí upozornění ignorujte, opravili jsme ho v pozdějším kurzu.

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě Visual Studio.

Otestování aplikace

Spusťte aplikaci a vyberte odkaz Filmová aplikace .

Pokud se zobrazí výjimka podobná následující, pravděpodobně jste příkaz v kroku migrace vynechaliUpdate-Database:

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

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

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

Pomocí EF Coremodelu se provádí přístup k datům. Model se skládá z tříd entit a kontextového objektu, 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ří Data/MvcMovieContext.cs třídu kontextu databáze:

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

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

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

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

Injektáž závislostí

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované v adresáři DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.

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

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

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

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

Prozkoumání vygenerované databáze připojovací řetězec

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

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
  }
}

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

Třída InitialCreate

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

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    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 a nakonfiguruje Id jako primární klíč.
  • InitialCreate.Down vrátí změny schématu provedené migrací Up .

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z 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 direktiva @model

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

MVC poskytuje možnost předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní předal model silného MoviesController typu ve třídě a zobrazeních.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler na movies kontroler, první segment adresy URL.
  • Akce na details, druhý segment adresy URL.
  • Hodnota id 1, poslední segment adresy URL.

id se předat pomocí řetězce dotazu, jak je znázorněno 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 (int?) v případech, kdy není zadána id hodnota.

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

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Kód vrátí podrobnosti o problému, pokud Movie je vlastnost kontextu dat null.

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí objektu silného Model typu. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silně zadán jako IEnumerable<Movie> objekt, každá položka ve smyčce je zadána jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

Další materiály

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

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

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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

  • Uživatel nemusí do pole kalendářního data zadávat informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

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

Otazník po string značí, že vlastnost je nullable. Další informace naleznete v tématu Odkazové typy s možnou hodnotou Null.

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

V nabídce Nástroje vyberte konzolu 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
Install-Package Microsoft.EntityFrameworkCore.SqlServer

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

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

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery a vyberte Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

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

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

Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcMovie.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 MvcMovie.Data.MvcMovieContext .
    • Vyberte Přidat.
  • Zobrazení a název kontroleru: Ponechte výchozí nastavení.
  • Vyberte Přidat.

Zachování výchozích hodnot kontextu přidání dat

Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.

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

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

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

  • Ovladač filmů: Controllers/MoviesController.cs
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index : Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/MvcMovieContext.cs

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

Vygenerované stránky se zatím nedají použít, protože databáze neexistuje. Spuštění aplikace a výběr odkazu Movie App má za následek nemožnost otevřít databázi nebo žádnou takovou tabulku: Chybová zpráva Film .

Vytvoření aplikace

Sestavení aplikace Kompilátor vygeneruje několik upozornění na způsob null zpracování hodnot. Další informace najdete v tomto problému GitHubu a odkazových typech s možnou hodnotou Null.

Chcete-li odstranit upozornění z odkazových typů s možnou MvcMovie.csproj hodnotou null, odeberte ze souboru následující řádek:

<Nullable>enable</Nullable>

Doufáme, že tento problém vyřešíme v příští verzi.

Počáteční migrace

EF CoreK vytvoření databáze použijte funkci Migrace. Migrace je sada nástrojů, které vytvářejí a aktualizují databázi tak, aby odpovídaly datovému modelu.

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

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

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

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

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

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

Předchozí upozornění ignorujte, opravili jsme ho v pozdějším kurzu.

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě 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 zmeškali krok migrace:

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

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

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

Pomocí EF Coremodelu se provádí přístup k datům. Model se skládá z tříd entit a kontextového objektu, 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ří Data/MvcMovieContext.cs třídu kontextu databáze:

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

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

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

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

Injektáž závislostí

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované v adresáři DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.

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

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

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<MvcMovieContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("MvcMovieContext")));

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

Prozkoumání vygenerované databáze připojovací řetězec

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

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

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

Třída InitialCreate

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

using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MvcMovie.Migrations
{
    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 a nakonfiguruje Id jako primární klíč.
  • InitialCreate.Down vrátí změny schématu provedené migrací Up .

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z 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 direktiva @model

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

MVC poskytuje možnost předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní předal model silného MoviesController typu ve třídě a zobrazeních.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler na movies kontroler, první segment adresy URL.
  • Akce na details, druhý segment adresy URL.
  • Hodnota id 1, poslední segment adresy URL.

id se předat pomocí řetězce dotazu, jak je znázorněno 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 (int?) v případech, kdy není zadána id hodnota.

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

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí objektu silného Model typu. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silně zadán jako IEnumerable<Movie> objekt, každá položka ve smyčce je zadána jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

Další materiály

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

Models/Movie.cs Aktualizujte soubor 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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

  • Uživatel nemusí do pole kalendářního data zadávat informace o čase.
  • Zobrazí se pouze datum, nikoli informace o čase.

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

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

V nabídce Nástroje vyberte konzolu 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 Serveru. Balíček zprostředkovatele nainstaluje jako EF Core závislost.
  • Nástroje používané balíčky nainstalované automaticky v kroku generování uživatelského rozhraní, dále v tomto kurzu.

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem na složku Kontrolery a vyberte Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

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

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

Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :

  • V rozevíracím seznamu Třída modelu vyberte Movie (MvcMovie.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 MvcMovie.Data.MvcMovieContext .
    • Vyberte Přidat.
  • Zobrazení a název kontroleru: Ponechte výchozí nastavení.
  • Vyberte Přidat.

Zachování výchozích hodnot kontextu přidání dat

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

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

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

  • Ovladač filmů: Controllers/MoviesController.cs
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index : Views/Movies/*.cshtml
  • Třída kontextu databáze: Data/MvcMovieContext.cs

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

Vygenerované stránky se zatím nedají použít, protože databáze neexistuje. Spuštění aplikace a výběr odkazu Movie App má za následek nemožnost otevřít databázi nebo žádnou takovou tabulku: Chybová zpráva Film .

Počáteční migrace

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

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

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

Add-Migration InitialCreate
Update-Database

  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

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

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

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

Předchozí upozornění ignorujte, opravili jsme ho v pozdějším kurzu.

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě 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 zmeškali krok migrace:

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

Poznámka:

Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

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

Pomocí EF Coremodelu se provádí přístup k datům. Model se skládá z tříd entit a kontextového objektu, 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ří Data/MvcMovieContext.cs třídu kontextu databáze:

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ří DbSet<Movie> vlastnost, která představuje filmy v databázi.

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby, jako je například kontext databáze, musí být registrovány v adresáři DI v Startup. Komponenty, které vyžadují tyto služby, jsou poskytovány prostřednictvím parametrů konstruktoru.

Controllers/MoviesController.cs V souboru konstruktor používá injektáž závislostí k vložení MvcMovieContext kontextu databáze do kontroleru. Kontext databáze se používá v každé z 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".

Prozkoumání vygenerované databáze připojovací řetězec

Generování uživatelského rozhraní přidalo do appsettings.json souboru připojovací ř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 načte ConnectionString konfigurační systém ASP.NET Core klíč ze appsettings.json souboru.

Třída InitialCreate

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

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 a nakonfiguruje Id jako primární klíč.
  • InitialCreate.Down vrátí změny schématu provedené migrací Up .

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z 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 direktiva @model

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

MVC poskytuje možnost předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní předal model silného MoviesController typu ve třídě a zobrazeních.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

  • Kontroler na movies kontroler, první segment adresy URL.
  • Akce na details, druhý segment adresy URL.
  • Hodnota id 1, poslední segment adresy URL.

id se předat pomocí řetězce dotazu, jak je znázorněno 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 (int?) v případech, kdy není zadána id hodnota.

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

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí objektu silného Model typu. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silně zadán jako IEnumerable<Movie> objekt, každá položka ve smyčce je zadána jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.

Protokolování SQL entity Framework Core

Konfiguraci protokolování obvykle zajišťuje oddíl Logging souborů appsettings.{Environment}.json. Pokud chcete protokolovat příkazy SQL, přidejte "Microsoft.EntityFrameworkCore.Database.Command": "Information" do appsettings.Development.json souboru:

{
  "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 příkazy SQL zobrazí na příkazovém řádku a v okně výstupu sady Visual Studio.

Další informace najdete v tématu Protokolování v .NET Core a ASP.NET Core a tento problém na GitHubu.

Další materiály

V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí aplikace MVC .

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

Vytvořené třídy modelu se označují jako třídy POCO z Plain Old CLR Objects. Třídy POCO nemají žádnou závislost na EF Core. Definují pouze vlastnosti dat, která mají být uložena v databázi.

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

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

Klikněte pravým tlačítkem myši na složku >Modely Přidat>třídu. Pojmenujte soubor Movie.cs.

Movie.cs Aktualizujte soubor 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 Movie obsahuje Id pole, které vyžaduje databáze pro primární klíč.

Atribut DataType pro ReleaseDate určuje typ dat (Date). S tímto atributem:

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

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

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

V nabídce Nástroje vyberte konzolu 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.SqlServer

Předchozí příkaz přidá EF Core zprostředkovatele SQL Serveru. Balíček zprostředkovatele nainstaluje jako EF Core závislost. Další balíčky se automaticky nainstalují v kroku generování uživatelského rozhraní později v tomto kurzu.

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

Ke koordinaci EF Core funkcí (vytvoření, čtení, aktualizace, odstranění) modelu Movie je potřeba třída kontextu databáze. Kontext databáze je odvozen z Microsoft.EntityFrameworkCore.DbContext a určuje entity, které se mají zahrnout do datového modelu.

Vytvořte složku Data .

Data/MvcMovieContext.cs Přidejte soubor 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 DbSet<Movie> pro sadu entit. V terminologii Entity Framework sada entit obvykle odpovídá databázové tabulce. Entita odpovídá řádku v tabulce.

Registrace kontextu databáze

ASP.NET Core se sestavuje pomocí injektáže závislostí (DI). Služby (například EF Core kontext databáze) musí být během spouštění aplikace zaregistrované v diplati. 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, se zobrazí později v kurzu. V této části zaregistrujete kontext databáze v kontejneru DI.

Na začátek Startup.cspříkazu přidejte následující using příkazy:

using MvcMovie.Data;
using Microsoft.EntityFrameworkCore;

Přidejte 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")));
}

Název připojovací řetězec se předává kontextu voláním metody na objektuDbContextOptions. V případě místního vývoje načte konfigurační systém ASP.NET Core připojovací řetězec ze appsettings.json souboru.

Prozkoumání připojovací řetězec databáze

Přidejte do appsettings.json souboru připojovací ř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"
  }
}

Sestavte projekt jako kontrolu chyb kompilátoru.

Stránky filmů vygenerované

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

V Průzkumník řešení klikněte pravým tlačítkem myši na složku > Kontrolery Přidat > novou vygenerovanou položku.

zobrazení výše uvedeného kroku

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

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

Dokončete dialogové okno Přidat kontroler:

  • Třída modelu: Film (MvcMovie.Models)
  • Třída kontextu dat: MvcMovieContext (MvcMovie.Data)

Přidání kontextu dat

  • Zobrazení: Ponechte výchozí nastavení jednotlivých možností zaškrtnuté.
  • Název kontroleru: Ponechte výchozí MoviesController.
  • Vyberte Přidat.

Visual Studio vytvoří:

  • Ovladač filmů (Controllers/MoviesController.cs)
  • Razor zobrazit soubory pro stránky Vytvořit, Odstranit, Podrobnosti, Upravit a Index (*Views/Movies/'.cshtml')

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

Nevygenerované stránky zatím nemůžete použít, protože databáze neexistuje. Pokud aplikaci spustíte a kliknete na odkaz Movie App , zobrazí se chybová zpráva Nejde otevřít databázi nebo žádná taková tabulka: Chybová zpráva Movie .

Počáteční migrace

EF CoreK vytvoření databáze použijte funkci Migrace. Migrace je sada nástrojů, které umožňují vytvořit a aktualizovat databázi tak, aby odpovídala datovému modelu.

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

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

Add-Migration InitialCreate
Update-Database
  • Add-Migration InitialCreate: Vygeneruje Migrations/{timestamp}_InitialCreate.cs soubor migrace. Argumentem InitialCreate je název migrace. Libovolný název lze použít, ale podle konvence je vybraný název, který popisuje migraci. Protož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ženo na modelu zadaném MvcMovieContext ve třídě.

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

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

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

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

Další informace o nástrojích PMC pro EF Corenaleznete v referenčních informacích EF Core k nástrojům – PMC v sadě Visual Studio.

InitialCreate – třída

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

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 Filmová aplikace .

    Pokud se zobrazí výjimka podobná některé z následujících možností:

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:

    Do pole pravděpodobně nebudete moct zadávat desetinné čárky Price . Aby bylo možné podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a pro jiné formáty kalendářních dat než v ANGLIČTINĚ, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tomto problému na GitHubu.

  • Otestujte stránky Upravit, Podrobnosti a Odstranit .

Injektáž závislostí v kontroleru

Controllers/MoviesController.cs Otevřete soubor 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é z metod CRUD v kontroleru.

Modely silného @model typu a klíčové slovo

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

MVC také umožňuje předat objekty modelu silného typu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus generování uživatelského rozhraní použil tento přístup (tj. předávání modelu silného MoviesController typu) se třídou a zobrazeními.

Prozkoumejte vygenerovanou Details metodu Controllers/MoviesController.cs v souboru:

// 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 obecně předává jako směrovací data. Například https://localhost:5001/movies/details/1 sady:

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

Řetězec dotazu můžete předat id také takto:

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

Parametr id je definován jako typ s možnou hodnotou null (int?), pokud není zadána hodnota ID.

Výraz lambda se předává k FirstOrDefaultAsync výběru filmových entit, které odpovídají hodnotě směrovacích dat nebo řetězce dotazu.

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

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

return View(movie);

Prozkoumejte obsah Views/Movies/Details.cshtml souboru:

@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á. Po vytvoření kontroleru videa se zahrnul následující @model příkaz:

@model MvcMovie.Models.Movie

Tato @model direktiva umožňuje přístup k filmu, který kontroler předal do zobrazení. Objekt Model je silně zadán. Například v Details.cshtml zobrazení kód předá každé pole DisplayNameFor videa pomocným rutině HTML DisplayFor se silným typem Model objektu. Metody Create a Edit zobrazení také předávají Movie objekt modelu.

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

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

Po vytvoření řadiče filmů obsahovalo generování uživatelského rozhraní v horní části Index.cshtml souboru následující @model příkaz:

@model IEnumerable<MvcMovie.Models.Movie>

Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal do zobrazení pomocí Model objektu, který je silně napsaný. Například v Index.cshtml zobrazení kód prochází filmy s příkazem nad objektem foreach 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, že Model objekt je silného typu (jako IEnumerable<Movie> objekt), je každá položka ve smyčce zadána jako Movie. Mimo jiné to znamená, že získáte kontrolu času kompilace kódu.

Další materiály