Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Note
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v .NET 10 verze tohoto článku.
Warning
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v .NET a .NET základních zásadách podpory. Aktuální verzi najdete v .NET 10 verze tohoto článku.
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy tvoří "Model" čá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 Vynechatelné referenční typy.
Přidání balíčků NuGet
Visual Studio automaticky nainstaluje požadované balíčky.
Sestavte projekt jako kontrolu chyb kompilátoru.
Návrh stránek filmů
Pomocí nástroje pro generování základní kostry můžete vytvořit Create, Read, Update a Delete (CRUD) stránky pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte Přidat > Nová scaffoldovaná položka.
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.
Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :
- V rozevíracím seznamu třídy Model 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 Database provider vyberte SQL Server.
- Zobrazení a název kontroleru: Ponechte výchozí nastavení.
- Vyberte Přidat.
Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.
Scaffolding přidá následující balíčky:
Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.VisualStudio.Web.CodeGeneration.Design
Vytváření základní struktury 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.csprojsouboru projektu. - Zaregistruje kontext databáze v
Program.cssouboru. - Přidá řetězec připojení k databázi do souboru
appsettings.json.
Automatické vytváření těchto souborů a jejich aktualizací se označuje jako scaffolding.
Stránky vytvořené pomocí šablony 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 Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkaz:
Add-Migration InitialCreate
-
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.
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 nepozorovaně zkrátí, pokud se nevejdou do výchozího nastavení přesnosti a škály. 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í metoduUpMigrations/{time-stamp}_InitialCreate.csv souboru, která vytvoří databázi.
Další informace o nástrojích PMC pro EF Core naleznete v tématu EF Core tools reference - PMC v 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 vynechali příkaz Update-Database v kroku migrace.
SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.
Note
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 dat než v angličtině, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tématu tohoto GitHub problému.
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í scaffoldingu 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.
Injekce závislostí
ASP.NET Core je sestaven s použitím injektáže závislostí (DI). Služby, jako je například kontext databáze, jsou registrované přes 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.
Scaffolding 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 čte připojovací řetězec databáze "MvcMovieContext".
Prozkoumejte vygenerovaný řetězec připojení k databázi
Generování uživatelského rozhraní přidalo připojovací řetězec do souboru appsettings.json:
{
"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"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrátí změny schématu provedené migracíUp.
Injektování 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 využívá Dependency Injection k vložení kontextu databáze (MvcMovieContext) do kontroléru. 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 silně typované objekty modelu do zobrazení. Tento přístup silného typu umožňuje kontrolu kódu v čase kompilace. Mechanismus scaffoldingu předal model silného typování ve třídě MoviesController 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:{PORT}/movies/details/1 nastavuje:
- Kontroler pro
movieskontroler, první segment adresy URL. - Akce pro
details, druhý segment URL. - Hodnota
idaž k 1, poslední segment adresy URL.
id lze předat pomocí řetězce dotazu, jak je uvedeno v následujícím příkladu:
https://localhost:{PORT}/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.
Lambda výraz se předává metodě FirstOrDefaultAsync k výběru filmových entit, které odpovídají směrovacím datům nebo hodnotě řetězce dotazu.
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
Pokud se film najde, instance modelu Movie se předá do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole filmu pomocníkům HTML DisplayNameFor a DisplayFor se silně typovaným Model objektem. Metody Create a Edit zobrazení také předávají Movie modelový objekt.
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í kontroleru pro filmy bylo v horní části souboru pomocí scaffoldingu zahrnuto následující prohlášení: @modelIndex.cshtml.
@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 pomocí příkazu, který iteruje přes foreach objekt 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ě typovaný jako IEnumerable<Movie>, každá položka ve smyčce je typovaná jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy představují část "Model" 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 Models, >Přidat>Třída. 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 části Nullovatelné odkazové typy.
Přidání balíčků NuGet
Visual Studio automaticky nainstaluje požadované balíčky.
Sestavte projekt jako kontrolu chyb kompilátoru.
Předvytvořené stránky filmů
Pomocí scaffoldovacího nástroje můžete vytvořit Create, Read, Update a Delete (CRUD) stránky pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte Přidat > Novou scaffoldovanou položku.
V dialogovém okně Přidat nový generovaný prvek:
- V levém podokně vyberte Nainstalované>Common>MVC.
- Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
- Vyberte Přidat.
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.
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.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.VisualStudio.Web.CodeGeneration.Design
Scaffolding vytváří 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
Aktualizace struktury zahrnuje následující:
- Vloží požadované odkazy na balíčky do
MvcMovie.csprojsouboru projektu. - Zaregistruje kontext databáze v
Program.cssouboru. - Přidá do souboru
appsettings.jsonpřipojovací řetězec k databázi.
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 Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkaz:
Add-Migration InitialCreate
-
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.
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 bez varová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í metoduUpMigrations/{time-stamp}_InitialCreate.csv souboru, která vytvoří databázi.
Další informace o nástrojích PMC pro EF Core naleznete v tématu EF Core tools reference - PMC v 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 vynechali příkaz Update-Database ve fázi migrace.
SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.
Note
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 GitHub issue.
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í pomocí scaffoldingu vytvoří třídu kontextu databáze Data/MvcMovieContext.cs.
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.
Injekce závislostí
ASP.NET Core je postavena pomocí vkládání závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované pomocí DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.
V souboru Controllers/MoviesController.cs konstruktor používá Dependency Injection k injektování MvcMovieContext kontextu databáze do kontroleru. Kontext databáze se používá v každé z metod CRUD v kontroleru.
Skafoldování vytvořilo 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".
Prozkoumejte vygenerovaný databázový připojovací řetězec
Generování scaffoldingu přidalo připojovací řetězec do souboru appsettings.json:
{
"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"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrátí změny schématu provedené migracíUp.
Injektování závislostí v kontroléru
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á Dependency Injection k vložení kontextu databáze (MvcMovieContext) do kontroléru. 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 .
Staticky typované modely 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 zobrazovacího rozhraní. Tento silně typovaný přístup 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:{PORT}/movies/details/1 nastaví:
- Směřování kontroleru na
movieskontroler, první segment adresy URL. - Akce týkající se
details, druhého segmentu URL adresy. - Hodnota
idje nastavena na 1, což je poslední segment adresy URL.
Lze id předat pomocí řetězce dotazu, jak je znázorněno v následujícím příkladu:
https://localhost:{PORT}/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.
Lambda výraz se předá FirstOrDefaultAsync metodě pro výběr entit filmů, které odpovídají datům trasy nebo hodnotě dotazu v řetězci.
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
Pokud se film najde, instance modelu Movie je předána do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole videa HTML pomocníkům DisplayNameFor a DisplayFor s objekt se silným typováním Model. Metody Create a zobrazení Edit také předávají modelový objekt Movie.
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í kontroleru pro filmy zahrnovalo generování v horní části souboru @model následující příkaz Index.cshtml.
@model IEnumerable<MvcMovie.Models.Movie>
Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí silně typovaného objektu Model. Například v Index.cshtml zobrazení kód prochází filmy pomocí příkazu pro silně typovaný objekt 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ě typovaný jako IEnumerable<Movie> objekt, každý prvek ve smyčce je typovaný jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy tvoří "Model" čá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 části Nulovatelné referenční typy.
Přidání balíčků NuGet
Visual Studio automaticky nainstaluje požadované balíčky.
Sestavte projekt jako kontrolu chyb kompilátoru.
Vytvoření šablony pro stránky filmů
Pomocí nástroje pro generování uživatelského rozhraní můžete vytvořit stránky Create, Read, Update a Delete (CRUD) pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte možnost Přidat > Nová generovaná položka.
V dialogovém okně Přidat novou scaffoldovanou položku
- V levém podokně vyberte Nainstalované>Společné>MVC.
- Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
- Vyberte Přidat.
Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :
- V rozevíracím seznamu Model class vyberte Movie (MvcMovie.Models).
-
V řádku třídy datového kontextu 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.
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.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.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.csprojsouboru projektu. - Zaregistruje kontext databáze v
Program.cssouboru. - Přidá řetězec připojení k databázi do souboru
appsettings.json.
Automatické vytváření těchto souborů a jejich aktualizací se označuje jako scaffolding.
Stránky vytvořené pomocí šablony 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 Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkazy:
Add-Migration InitialCreate
Update-Database
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí metoduUpMigrations/{time-stamp}_InitialCreate.csv 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 bez varová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 Core naleznete v tématu EF Core tools reference - PMC v 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 vynechali příkaz Update-Database ve kroku migrace:
SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.
Note
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 dat než v angličtině, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tématu tohoto GitHub problému.
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í scaffoldingu 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.
Injekce závislostí
ASP.NET Core je sestavena pomocí injektáže závislostí (DI). Služby, jako je například kontext databáze, jsou registrované přes 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.
Scaffolding 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 čte připojovací řetězec databáze "MvcMovieContext".
Prozkoumejte vygenerovaný řetězec připojení k databázi
Generování uživatelského rozhraní přidalo připojovací řetězec do souboru appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrá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á Dependency Injection k vložení kontextu databáze (MvcMovieContext) do řadiče. Kontext databáze se používá v každé z metod CRUD v kontroleru.
Otestujte stránku vytvoření. Zadejte a odešlete data.
Otestujte stránky Upravit, Podrobnosti a Odstranit .
Staticky typované modely 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 zobrazovacího rozhraní. Tento silně typovaný přístup 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 nastaví:
- Směřování kontroleru na
movieskontroler, první segment adresy URL. - Akce týkající se
details, druhého segmentu URL adresy. - Hodnota
idje nastavena na 1, což je poslední segment adresy URL.
Lze id 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.
Lambda výraz se předá FirstOrDefaultAsync metodě pro výběr entit filmů, které odpovídají datům trasy nebo hodnotě dotazu v řetězci.
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
Pokud se film najde, instance modelu Movie je předána do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole videa HTML pomocníkům DisplayNameFor a DisplayFor s objekt se silným typováním Model. Metody Create a zobrazení Edit také předávají modelový objekt Movie.
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í kontroleru pro filmy zahrnovalo generování v horní části souboru @model následující příkaz Index.cshtml.
@model IEnumerable<MvcMovie.Models.Movie>
Direktiva @model umožňuje přístup k seznamu filmů, které řadič předal zobrazení pomocí silně typovaného objektu Model. Například v Index.cshtml zobrazení kód prochází filmy pomocí příkazu pro silně typovaný objekt 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ě typovaný jako IEnumerable<Movie> objekt, každý prvek ve smyčce je typovaný jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí komponenty Model 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 části Nulovatelné referenční typy.
Přidání balíčků NuGet
Visual Studio automaticky nainstaluje požadované balíčky.
Sestavte projekt jako kontrolu chyb kompilátoru.
Stránky filmů připravené jako šablona
Pomocí nástroje pro vytváření schémat můžete vytvořit stránky Create, Read, Update a Delete (CRUD) pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte složku Přidat > Nová vygenerovaná položka.
V dialogovém okně Přidat novou vygenerovanou položku :
- V levém podokně vyberte Nainstalované>Common>MVC.
- Vyberte kontroler MVC se zobrazeními pomocí Entity Frameworku.
- Vyberte Přidat.
Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :
- V rozevíracím seznamu Model vyberte Movie (MvcMovie.Models).
- V řádku Data context class 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.
Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.
Scaffolding přidá následující balíčky:
Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.VisualStudio.Web.CodeGeneration.Design
Funkce scaffolding 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.csprojsouboru projektu. - Zaregistruje kontext databáze v
Program.cssouboru. - Přidá připojovací řetězec do souboru
appsettings.json.
Automatické vytváření těchto souborů a jejich aktualizací se označuje jako scaffolding.
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 Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkazy:
Add-Migration InitialCreate
Update-Database
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí metoduUpMigrations/{time-stamp}_InitialCreate.csv 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 bez varová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 Core naleznete v tématu EF Core tools reference - PMC v 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 vynechali příkaz Update-Database ve kroku migrace:
SqlException: Cannot open database "MvcMovieContext-1" requested by the login. The login failed.
Note
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 GitHub issue.
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í pomocí scaffoldingu vytvoří třídu kontextu databáze Data/MvcMovieContext.cs.
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.
Injekce závislostí
ASP.NET Core je postavena pomocí vkládání závislostí (DI). Služby, jako je kontext databáze, jsou zaregistrované pomocí DI v Program.cs. Tyto služby jsou poskytovány komponentám, které je vyžadují prostřednictvím parametrů konstruktoru.
V souboru Controllers/MoviesController.cs konstruktor používá Dependency Injection k injektování MvcMovieContext kontextu databáze do kontroleru. Kontext databáze se používá v každé z metod CRUD v kontroleru.
Skafoldování vytvořilo 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".
Prozkoumejte vygenerovaný databázový připojovací řetězec
Generování scaffoldingu přidalo připojovací řetězec do souboru appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MvcMovieContext": "Data Source=MvcMovieContext-ea7a4069-f366-4742-bd1c-3f753a804ce1.db"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrátí změny schématu provedené migracíUp.
Injektování závislostí v kontroléru
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á Dependency Injection k vložení kontextu databáze (MvcMovieContext) do kontroléru. 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 silně typovaný přístup umožňuje kontrolu kódu při kompilaci. 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 nastavuje:
- Kontrolér u
movieskontroléru, který určuje první segment adresy URL. - Akce na
details, druhý segment adresy URL. -
idna 1, poslední segment adresy URL.
id může být předán 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, instance modelu Movie se předá do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole filmu pomocníkům HTML DisplayNameFor a DisplayFor se silně typovaným Model objektem. Metody Create a Edit zobrazení také předávají Movie modelový objekt.
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í kontroleru pro filmy bylo v horní části souboru pomocí scaffoldingu zahrnuto následující prohlášení: @modelIndex.cshtml.
@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 pomocí příkazu, který iteruje přes foreach objekt 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ě typovaný jako IEnumerable<Movie>, každá položka ve smyčce je typovaná jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy jsou součástí komponenty Model 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 Models>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 Nullable odkazové typy.
Přidání balíčků NuGet
V nabídce Tools vyberte NuGet Správce balíčků>Správce balíčků Console (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 SQL Server EF Core. Balíček zprostředkovatele nainstaluje balíček EF Core jako závislost.
- Nástroje, které používají balíčky automaticky nainstalované v kroku vytváření struktury kódu, dále v tomto kurzu.
Sestavte projekt jako kontrolu chyb kompilátoru.
Základní struktura stránek filmů
Pomocí scaffoldovacího nástroje můžete vytvořit Create, Read, Update a Delete (CRUD) stránky pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte Přidat > Novou scaffoldovanou položku.
V dialogovém okně Přidat Scaffold vyberte MVC kontroler se zobrazeními pomocí Entity Framework a přidejte >.
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.
Pokud se zobrazí chybová zpráva, vyberte Přidat podruhé a zkuste to znovu.
Aktualizace struktury zahrnuje následující:
- Vloží požadované odkazy na balíčky do
MvcMovie.csprojsouboru projektu. - Zaregistruje kontext databáze v
Program.cssouboru. - Přidá připojovací řetězec do souboru
appsettings.json.
Scaffolding vytváří 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 jejich aktualizací se označuje jako scaffolding.
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 GitHub problému a odkazové typy s možnou hodnotou null.
Chcete-li odstranit upozornění z nulovatelných referenčních typů, odeberte ze souboru tento řádek:
<Nullable>enable</Nullable>
Doufáme, že tento problém vyřešíme v příští verzi.
Počáteční migrace
EF Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkazy:
Add-Migration InitialCreate
Update-Database
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí metoduUpMigrations/{time-stamp}_InitialCreate.csv 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 bez varová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 Core naleznete v tématu EF Core tools reference - PMC v 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.
Note
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 dat než v angličtině, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tématu tohoto GitHub problému.
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í scaffoldingu 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.
Injekce závislostí
ASP.NET Core je sestaven s použitím injektáže závislostí (DI). Služby, jako je například kontext databáze, jsou registrované přes 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.
Scaffolding 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 čte připojovací řetězec databáze "MvcMovieContext".
Prozkoumejte vygenerovaný řetězec připojení k databázi
Generování uživatelského rozhraní přidalo připojovací řetězec do souboru appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-7dc5;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrátí změny schématu provedené migracíUp.
Injektování 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 využívá Dependency Injection k vložení kontextu databáze (MvcMovieContext) do kontroléru. 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 silně typovaný přístup umožňuje kontrolu kódu při kompilaci. 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 nastavuje:
- Kontrolér u
movieskontroléru, který určuje první segment adresy URL. - Akce na
details, druhý segment adresy URL. -
idna 1, poslední segment adresy URL.
id může být předán 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, instance modelu Movie se předá do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole filmu pomocníkům HTML DisplayNameFor a DisplayFor se silně typovaným Model objektem. Metody Create a Edit zobrazení také předávají Movie modelový objekt.
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í kontroleru pro filmy bylo v horní části souboru pomocí scaffoldingu zahrnuto následující prohlášení: @modelIndex.cshtml.
@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 pomocí příkazu, který iteruje přes foreach objekt 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ě typovaný jako IEnumerable<Movie>, každá položka ve smyčce je typovaná jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy tvoří "Model" čá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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console (PMC).
V PMC spusťte následující příkaz:
Install-Package Microsoft.EntityFrameworkCore.Design
Předchozí příkazy přidávají:
- Poskytovatel SQL Server EF Core. Balíček zprostředkovatele nainstaluje balíček EF Core jako závislost.
- Nástroje, které používají balíčky automaticky nainstalované v kroku vytváření struktury kódu, dále v tomto kurzu.
Sestavte projekt jako kontrolu chyb kompilátoru.
Návrh stránek filmů
Pomocí scaffoldovacího nástroje můžete vytvořit stránky Create, Read, Update a Delete (CRUD) pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem na složku Controllers a vyberte Přidat > Nový generovaný prvek.
V dialogovém okně Přidat Scaffold vyberte MVC kontroler se zobrazeními pomocí Entity Framework a přidejte >.
Dokončete přidání kontroleru MVC se zobrazeními pomocí dialogového okna Entity Framework :
- V rozevíracím seznamu Třída Model 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.
Generování uživatelského rozhraní aktualizuje následující:
- Vloží požadované odkazy na balíčky do
MvcMovie.csprojsouboru projektu. - Zaregistruje kontext databáze v
Startup.ConfigureServicesStartup.cssouboru. - Přidá řetězec připojení k databázi do souboru
appsettings.json.
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í kostry.
Stránky vytvořené pomocí šablony 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 Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console .
V konzole Správce balíčků (PMC) zadejte následující příkazy:
Add-Migration InitialCreate
Update-Database
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí metoduUpMigrations/{time-stamp}_InitialCreate.csv 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 bez varová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 Core naleznete v tématu EF Core tools reference - PMC v 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.
Note
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 dat než v angličtině, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tématu tohoto GitHub problému.
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í scaffoldingu 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 je sestaven s použitím 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.
Skafoldování vytvořilo 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".
Prozkoumejte vygenerovaný databázový připojovací řetězec
Generování scaffoldingu přidalo připojovací řetězec do souboru appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MvcMovieContext": "Server=(localdb)\\mssqllocaldb;Database=MvcMovieContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Pro místní vývoj ASP.NET Core konfigurační systém přečte klíč ConnectionString ze souboru appsettings.json.
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.Upvytvoří tabulku Movie a nakonfigurujeIdjako primární klíč. -
InitialCreate.Downvrátí změny schématu provedené migracíUp.
Injektování závislostí v kontroléru
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á Dependency Injection k vložení kontextu databáze (MvcMovieContext) do kontroléru. 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 typování umožňuje kontrolu kódu během kompilace. Mechanismus scaffoldingu předal silně typovaný model 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 nastaví:
- Kontroler do
movieskontroleru, první segment URL. - Akce se týká
details, druhého segmentu adresy URL. - Nastavení
idna 1, poslední segment adresy URL.
Dá 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.
Lambda výraz se předá FirstOrDefaultAsync metodě k výběru filmových entit, které odpovídají údajům trasy nebo hodnotě řetězce dotazu.
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
Pokud se film najde, instance modelu Movie se předá do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole filmu pomocníkům HTML DisplayNameFor a DisplayFor se silně typovaným Model objektem. Metody Create a Edit zobrazení také předávají Movie modelový objekt.
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í kontroleru pro filmy bylo v horní části souboru pomocí scaffoldingu zahrnuto následující prohlášení: @modelIndex.cshtml.
@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 pomocí příkazu, který iteruje přes foreach objekt 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ě typovaný jako IEnumerable<Movie>, každá položka ve smyčce je typovaná jako Movie. Kromě dalších výhod kompilátor ověřuje typy používané v kódu.
Protokolování SQL v 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 souboru appsettings.Development.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
}
},
"AllowedHosts": "*"
}
V předchozím kódu JSON se příkazy SQL zobrazí na příkazovém řádku a v okně výstupu Visual Studio.
Další informace najdete v následujících zdrojích informací:
- Logging v .NET a ASP.NET Core
-
Šablona ASP.NET ve výchozím nastavení zakáže EF Core protokolování SQL (
dotnet/aspnetcore#32977)
Dodatečné zdroje
V tomto kurzu se přidávají třídy pro správu filmů v databázi. Tyto třídy tvoří "Model" čá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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console (PMC).
V PMC spusťte následující příkaz:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Předchozí příkaz přidá poskytovatele SQL Serveru EF Core. Balíček zprostředkovatele nainstaluje balíček EF Core jako závislost. Další balíčky se automaticky nainstalují během kroku scaffoldování později v tomto návodu.
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 je sestavena pomocí injektáže závislostí (DI). Služby (například EF Core kontext databáze) musí být během spouštění aplikace registrovány v DI. Komponenty, které vyžadují tyto služby (například Razor Stránky), jsou poskytovány prostřednictvím parametrů konstruktoru. Kód konstruktoru, který získá instanci kontextu databáze, se zobrazí později v kurzu. V této části zaregistrujete kontext databáze v kontejneru DI.
Přidejte následující using příkazy na začátek Startup.cs:
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 objektu DbContextOptions. Pro místní vývoj ASP.NET Core konfigurační systém přečte připojovací řetězec ze souboru appsettings.json.
Prozkoumejte připojovací řetězec databáze
Do souboru appsettings.json přidejte 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.
Základní struktura stránek filmů
Pomocí nástroje pro generování stránek můžete vytvořit stránky pro operace CRUD (Create, Read, Update, Delete) pro model filmu.
V Průzkumník řešení klikněte pravým tlačítkem myši na složku Controllers> Přidat > Nová položka s scaffoldingem.
V dialogovém okně Přidat Scaffold vyberte MVC kontroler se zobrazeními pomocí Entity Framework a přidejte >.
Vyplňte dialogové okno Přidat řadič:
- Třída modelu:Movie (MvcMovie.Models)
- Třída kontextu dat:MvcMovieContext (MvcMovie.Data)
- 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 scaffolding.
Vygenerované stránky nemůžete použít, protože databáze neexistuje. Pokud aplikaci spustíte a kliknete na odkaz Movie App, zobrazí se Nelze otevřít databázi nebo žádná taková tabulka: Movie.
Počáteční migrace
EF Core K 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 Tools vyberte NuGet Správce balíčků>Správce balíčků Console (PMC).
V PMC zadejte následující příkazy:
Add-Migration InitialCreate
Update-Database
Add-Migration InitialCreate: VygenerujeMigrations/{timestamp}_InitialCreate.cssoubor migrace. ArgumentemInitialCreateje 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 ve tříděMvcMovieContext.Update-Database: Aktualizuje databázi na nejnovější migraci, kterou vytvořil předchozí příkaz. Tento příkaz spustí metoduUpMigrations/{time-stamp}_InitialCreate.csv 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 bez varová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 Core naleznete v tématu EF Core tools reference - PMC v Visual Studio.
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>(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ření. Zadejte a odešlete data.
Note
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 dat než v angličtině, musí být aplikace globalizována. Pokyny ke globalizaci najdete v tématu tohoto GitHub problému.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á Dependency Injection k vložení kontextu databáze (MvcMovieContext) do řadiče. 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 silně typované objekty modelu do zobrazení. Tento silně typovaný přístup umožňuje kontrolu kódu v čase kompilace. Mechanismus scaffolding použil tento přístup (tj. předávání silně typovaného modelu) s třídou MoviesController 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 nastaví:
- Kontroler na
movieskontroler (první segment adresy URL). - Akce pro druhý segment adresy URL
details. - ID na hodnotu 1 (poslední segment URL adresy).
Ř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á do FirstOrDefaultAsync pro výběr 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, instance modelu Movie je předána do zobrazení Details.
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ě typovaný. Například v Details.cshtml zobrazení kód předá každé pole videa HTML pomocníkům DisplayNameFor a DisplayFor s objekt se silným typováním Model. Metody Create a zobrazení Edit také předávají modelový objekt Movie.
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í kontroleru pro filmy zahrnovalo generování v horní části souboru @model následující příkaz Index.cshtml.
@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 striktně typovaný. Například v Index.cshtml zobrazení kód prochází filmy pomocí příkazu pro silně typovaný objekt 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.