Razor Stránky s Entity Framework Core v ASP.NET Core – kurz 1 z 8
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tom Dykstra, Jeremy Likness a Jon P Smith
Toto je první v řadě kurzů, které ukazují, jak používat Entity Framework (EF) Core v aplikaci ASP.NET Core Razor Pages . Kurzy vytvářejí web pro fiktivní univerzitu Contoso. Web obsahuje funkce, jako je přijetí studentů, vytvoření kurzu a zadání instruktora. Tento kurz používá první přístup kódu. Informace o sledování tohoto kurzu s využitím prvního přístupu k databázi najdete v tomto problému na GitHubu.
Stáhněte nebo zobrazte dokončenou aplikaci. Pokyny ke stažení
Požadavky
- Pokud s stránkami teprve začínáteRazor, projděte si před zahájením této série kurzů Začínáme se stránkamiRazor.
- Sada Visual Studio 2022 se sadou funkcí Vývoj pro ASP.NET a web
- Sada .NET 6.0 SDK
Databázové stroje
Pokyny pro Visual Studio používají SQL Server LocalDB, verzi SQL Serveru Express, která běží jenom ve Windows.
Řešení problému
Pokud narazíte na problém, který nemůžete vyřešit, porovnejte kód s dokončeným projektem. Dobrý způsob, jak získat pomoc, je odesláním otázky na StackOverflow.com pomocí značky ASP.NET Core nebo značkyEF Core.
Ukázková aplikace
Aplikace vytvořená v těchto kurzech je základní web pro vysokoškoláky. Uživatelé můžou zobrazit a aktualizovat informace o studentech, kurzech a instruktorech. Tady je několik obrazovek vytvořených v kurzu.
Styl uživatelského rozhraní tohoto webu je založený na předdefinovaných šablonách projektů. Tento kurz se zaměřuje na použití EF Core s ASP.NET Core, nikoli na přizpůsobení uživatelského rozhraní.
Volitelné: Sestavení ukázkového stažení
Tento krok je nepovinný. Sestavení dokončené aplikace se doporučuje, když máte problémy, které nemůžete vyřešit. Pokud narazíte na problém, který nemůžete vyřešit, porovnejte kód s dokončeným projektem. Pokyny ke stažení
Výběrem ContosoUniversity.csproj
otevřete projekt.
Sestavte projekt.
V konzole Správce balíčků (PMC) spusťte následující příkaz:
Update-Database
Spuštěním projektu zasadíte databázi.
Vytvoření projektu webové aplikace
Spusťte Visual Studio 2022 a vyberte Vytvořit nový projekt.
V dialogovém okně Vytvořit nový projekt vyberte ASP.NET Core Web App a pak vyberte Další.
V dialogovém okně Konfigurovat nový projekt zadejte
ContosoUniversity
název projektu. Je důležité pojmenovat projekt ContosoUniversity, včetně porovnávání velkých písmen, aby se obory názvů při kopírování a vkládání ukázkového kódu shodovaly.Vyberte Další.
V dialogovém okně Další informace vyberte .NET 6.0 (dlouhodobá podpora) a pak vyberte Vytvořit.
Nastavení stylu webu
Zkopírujte a vložte do Pages/Shared/_Layout.cshtml
souboru následující kód:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/ContosoUniversity.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Soubor rozložení nastaví záhlaví webu, zápatí a nabídku. Předchozí kód provede následující změny:
- Každý výskyt "ContosoUniversity" na "Contoso University". Existují tři výskyty.
- Položky Home nabídky a Privacy položky nabídky se odstraní.
- Položky jsou přidány pro About, Students, Courses, Instructors a Departments.
Nahraďte Pages/Index.cshtml
obsah souboru následujícím kódem:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
@* <a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
*@ </p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
@* <a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
*@ </p>
</div>
</div>
</div>
</div>
Předchozí kód nahradí text o ASP.NET Core textem o této aplikaci.
Spuštěním aplikace ověřte, že se home zobrazí stránka.
Datový model
Následující části vytvoří datový model:
Student se může zaregistrovat do libovolného počtu kurzů a kurz může mít v něm zaregistrovaný libovolný počet studentů.
Entita Student
- Ve složce projektu vytvořte složku Models .
- Vytvořte
Models/Student.cs
pomocí následujícího kódu:namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Vlastnost ID
se stane sloupcem primárního klíče v tabulce databáze, která odpovídá této třídě. Ve výchozím nastavení interpretuje vlastnost, EF Core která je pojmenovaná ID
nebo classnameID
jako primární klíč. Proto je alternativou automaticky rozpoznaný název primárního Student
klíče StudentID
třídy . Další informace najdete v tématu EF Core – Klíče.
Vlastnost Enrollments
je navigační vlastnost. Vlastnosti navigace obsahují další entity, které souvisejí s touto entitou. V tomto případě Enrollments
vlastnost Student
entity obsahuje všechny Enrollment
entity, které se vztahují k tomuto studentu. Pokud má například řádek Student v databázi dva související řádky registrace, Enrollments
navigační vlastnost obsahuje tyto dvě entity registrace.
V databázi se řádek Registrace vztahuje k řádku Student, pokud jeho StudentID
sloupec obsahuje hodnotu ID studenta. Předpokládejme například, že řádek Student má ID=1. Související řádky registrace budou mít StudentID
hodnotu = 1. StudentID
je cizí klíč v tabulce Registrace.
Vlastnost je definována Enrollments
, protože ICollection<Enrollment>
může existovat více souvisejících entit registrace. Lze použít jiné typy kolekcí, například List<Enrollment>
.HashSet<Enrollment>
Při ICollection<Enrollment>
použití EF Core vytvoří kolekci HashSet<Enrollment>
ve výchozím nastavení.
Entita Registrace
Vytvořte Models/Enrollment.cs
pomocí následujícího kódu:
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
[DisplayFormat(NullDisplayText = "No grade")]
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Vlastnost EnrollmentID
je primární klíč; tato entita používá classnameID
vzor místo ID
sebe sama. V případě produkčního datového modelu si mnoho vývojářů zvolí jeden vzor a konzistentně ho použije. V tomto kurzu se obě používají k ilustraci toho, že obě fungují. Použití ID
bez classname
usnadnění implementace některých druhů změn datového modelu.
Vlastnost Grade
je .enum
Otazník za Grade
deklaraci typu označuje, že Grade
vlastnost je nullable. Známka, která má hodnotu null, se liší od nulové známky – hodnota null znamená, že známka není známa nebo ještě nebyla přiřazena.
Vlastnost StudentID
je cizí klíč a odpovídající navigační vlastnost je Student
. Entita Enrollment
je přidružená k jedné Student
entitě, takže vlastnost obsahuje jednu Student
entitu.
Vlastnost CourseID
je cizí klíč a odpovídající navigační vlastnost je Course
. Entita Enrollment
je přidružená k jedné Course
entitě.
EF Core interpretuje vlastnost jako cizí klíč, pokud je pojmenovaná <navigation property name><primary key property name>
. Je to napříkladStudentID
cizí klíč pro Student
navigační vlastnost, protože Student
primární klíč entity je ID
. Vlastnosti cizího klíče lze také pojmenovat <primary key property name>
. Například vzhledem k tomu, CourseID
že Course
primární klíč entity je CourseID
.
Entita Course
Vytvořte Models/Course.cs
pomocí následujícího kódu:
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Vlastnost Enrollments
je navigační vlastnost. Entita Course
může souviset s libovolným počtem Enrollment
entit.
Atribut DatabaseGenerated
umožňuje aplikaci místo vygenerování databáze zadat primární klíč.
Sestavení aplikace Kompilátor vygeneruje několik upozornění na způsob null
zpracování hodnot. Další informace najdete v tomto problému Na GitHubu, odkazových typech s možnou hodnotou Null a Kurz: Záměr návrhu jasněji vyjádřete s odkazovými typy s možnou hodnotou null a nenulovou hodnotou.
Chcete-li odstranit upozornění z odkazových typů s možnou ContosoUniversity.csproj
hodnotou null, odeberte ze souboru následující řádek:
<Nullable>enable</Nullable>
Modul generování uživatelského rozhraní v současné době nepodporuje odkazové typy s možnou hodnotou null, a proto ani modely použité v generování není možné.
Odeberte poznámku typu odkazu s možnou ?
hodnotou null, public string? RequestId { get; set; }
Pages/Error.cshtml.cs
aby se projekt sestavil bez upozornění kompilátoru.
Vygenerované stránky studentů
V této části se k vygenerování používá nástroj pro generování uživatelského rozhraní ASP.NET Core:
- Třída EF Core
DbContext
. Kontext je hlavní třída, která koordinuje funkce Entity Framework pro daný datový model. Odvozuje z Microsoft.EntityFrameworkCore.DbContext třídy. - Razor stránky, které zpracovávají operace vytvoření, čtení, aktualizace a odstranění (CRUD) pro entitu
Student
.
- Vytvořte složku Pages/Students .
- V Průzkumník řešení klikněte pravým tlačítkem na složku Pages/Students a vyberte Přidat>novou vygenerovanou položku.
- V dialogovém okně Přidat novou položku uživatelského rozhraní:
- Na levé kartě vyberte Nainstalované > společné >Razor stránky.
- Vyberte Razor stránky pomocí entity Framework (CRUD)>ADD.
- V dialogovém okně Přidat Razor stránky pomocí entity Framework (CRUD):
- V rozevíracím seznamu Třída modelu vyberte Student (ContosoUniversity.Models).
- V řádku třídy kontextu dat vyberte znaménko + (plus).
- Změňte název kontextu dat tak, aby končil
SchoolContext
místoContosoUniversityContext
. Aktualizovaný název kontextu:ContosoUniversity.Data.SchoolContext
- Výběrem možnosti Přidat dokončíte přidání třídy kontextu dat.
- Výběrem možnosti Přidat dokončete dialogové okno Přidat Razor stránky .
- Změňte název kontextu dat tak, aby končil
Automaticky se nainstalují následující balíčky:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
Pokud předchozí krok selže, sestavte projekt a zopakujte krok generování.
Proces generování uživatelského rozhraní:
- Vytvoří Razor stránky ve složce Pages/Students :
Create.cshtml
aCreate.cshtml.cs
Delete.cshtml
aDelete.cshtml.cs
Details.cshtml
aDetails.cshtml.cs
Edit.cshtml
aEdit.cshtml.cs
Index.cshtml
aIndex.cshtml.cs
- Vytvoří
Data/SchoolContext.cs
. - Přidá kontext do injektáže závislostí v
Program.cs
souboru . - Přidá databázi připojovací řetězec do
appsettings.json
.
Připojovací řetězec databáze
Nástroj pro generování uživatelského rozhraní vygeneruje v souboru připojovací řetězecappsettings.json
.
Připojovací řetězec určuje SQL Server LocalDB:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext-0e9;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB je zjednodušená verze databázového stroje SQL Server Express a je určená pro vývoj aplikací, nikoli pro produkční použití. Ve výchozím nastavení LocalDB vytvoří .mdf soubory v C:/Users/<user>
adresáři.
Aktualizace třídy kontextu databáze
Hlavní třída, která koordinuje EF Core funkce pro daný datový model, je třída kontextu databáze. Kontext je odvozen z Microsoft.EntityFrameworkCore.DbContext. Kontext určuje, které entity jsou součástí datového modelu. V tomto projektu má třída název SchoolContext
.
Aktualizujte Data/SchoolContext.cs
následujícím kódem:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Předchozí kód se změní z jednotného čísla DbSet<Student> Student
na množné číslo DbSet<Student> Students
. Pokud chcete, aby Razor kód Stránky odpovídal novému DBSet
názvu, proveďte globální změnu z: _context.Student.
k: _context.Students.
Existuje 8 výskytů.
Vzhledem k tomu, že sada entit obsahuje více entit, mnoho vývojářů dává přednost DBSet
názvům vlastností v množném čísle.
Zvýrazněný kód:
- Vytvoří DbSet<TEntity> vlastnost pro každou sadu entit. V EF Core terminologii:
- Sada entit obvykle odpovídá databázové tabulce.
- Entita odpovídá řádku v tabulce.
- Zavolá metodu OnModelCreating.
OnModelCreating
:- Volá se, když
SchoolContext
byl inicializován, ale před tím, než byl model zabezpečen a použit k inicializaci kontextu. - Je vyžadováno, protože v pozdější části kurzu
Student
bude mít entita odkazy na ostatní entity.
- Volá se, když
Doufáme, že tento problém vyřešíme v budoucí verzi.
Program.cs
ASP.NET Core se sestavuje pomocí injektáže závislostí. Služby, jako SchoolContext
je například injektáž závislostí, se registrují během spuštění aplikace. 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.
Nástroj pro generování uživatelského rozhraní automaticky zaregistroval třídu kontextu s kontejnerem injektáže závislostí.
Následující zvýrazněné řádky přidal scaffolder:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
Název připojovací řetězec se předává kontextu voláním metody na objektuDbContextOptions. Pro místní vývoj načte konfigurační systém ASP.NET Core připojovací řetězec ze appsettings.json
souboru.appsettings.Development.json
Přidání filtru výjimek databáze
Přidejte AddDatabaseDeveloperPageExceptionFilter a UseMigrationsEndPoint jak je znázorněno v následujícím kódu:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
Přidejte balíček NuGet Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.
V konzole Správce balíčků zadejte následující příkaz, který přidá balíček NuGet:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Balíček Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
NuGet poskytuje ASP.NET middlewaru Core pro chybové stránky Entity Framework Core. Tento middleware pomáhá zjišťovat a diagnostikovat chyby při migracích Entity Framework Core.
Poskytuje AddDatabaseDeveloperPageExceptionFilter
užitečné informace o chybách chyb ve vývojovém prostředí pro chyby migrace EF.
Vytvoření databáze
Aktualizujte Program.cs
databázi, pokud neexistuje:
using ContosoUniversity.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SchoolContext")));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
else
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Metoda EnsureCreated neprobíná žádnou akci, pokud existuje databáze pro kontext. Pokud žádná databáze neexistuje, vytvoří databázi a schéma. EnsureCreated
umožňuje následující pracovní postup pro zpracování změn datového modelu:
- Odstraňte databázi. Všechna existující data se ztratí.
- Změňte datový model. Můžete například přidat
EmailAddress
pole. - Spustit aplikaci.
EnsureCreated
vytvoří databázi s novým schématem.
Tento pracovní postup funguje v rané fázi vývoje, když se schéma rychle vyvíjí, pokud data nemusí být zachována. Situace se liší, když je potřeba zachovat data zadaná do databáze. V takovém případě použijte migrace.
Později v sérii kurzů se databáze odstraní, kterou vytvořila EnsureCreated
a migrace se použije. Databázi vytvořenou pomocí EnsureCreated
migrací nejde aktualizovat.
Otestování aplikace
- Spustit aplikaci.
- Vyberte odkaz Studenti a pak vytvořte nový.
- Otestujte odkazy Upravit, Podrobnosti a Odstranit.
Počáteční hodnota databáze
Metoda EnsureCreated
vytvoří prázdnou databázi. Tato část přidá kód, který naplní databázi testovacími daty.
Vytvořte Data/DbInitializer.cs
pomocí následujícího kódu:
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kód zkontroluje, jestli v databázi nejsou žádní studenti. Pokud nejsou žádní studenti, přidá do databáze testovací data. Vytvoří testovací data v polích místo List<T>
kolekcí pro optimalizaci výkonu.
- V
Program.cs
, odebrat//
zDbInitializer.Initialize
řádku:
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
DbInitializer.Initialize(context);
}
Pokud je aplikace spuštěná, zastavte ji a v konzole Správce balíčků (PMC) spusťte následující příkaz:
Drop-Database -Confirm
Odpovězte na
Y
odstranění databáze.
- Restartujte aplikaci.
- Výběrem stránky Studenti zobrazíte počáteční data.
Zobrazení databáze
- V nabídce Zobrazit v sadě Visual Studio otevřete SQL Server Průzkumník objektů (SSOX).
- V nástroji SSOX vyberte (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Název databáze se vygeneruje z názvu kontextu, který jste zadali dříve, a navíc pomlčku a identifikátor GUID.
- Rozbalte uzel Tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit data zobrazte sloupce vytvořené a řádky vložené do tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit kód zobrazte, jak se
Student
model mapuje naStudent
schéma tabulky.
Asynchronní metody EF ve webových aplikacích ASP.NET Core
Asynchronní programování je výchozí režim pro ASP.NET Core a EF Core.
Webový server má k dispozici omezený počet vláken a v situacích s vysokým zatížením se můžou používat všechna dostupná vlákna. V takovém případě nemůže server zpracovat nové požadavky, dokud se vlákna nevysadí. V synchronním kódu může být mnoho vláken svázané, zatímco nefungují, protože čekají na dokončení vstupně-výstupních operací. Když proces čeká na dokončení vstupně-výstupních operací, v asynchronním kódu se jeho vlákno uvolní, aby server používal ke zpracování dalších požadavků. V důsledku toho asynchronní kód umožňuje efektivnější použití serverových prostředků a server dokáže zpracovat větší provoz bez zpoždění.
Asynchronní kód zavádí v době běhu malé režijní náklady. U situací s nízkým provozem je dosažení výkonu zanedbatelné, zatímco u vysokých dopravních situací je potenciální zlepšení výkonu podstatné.
V následujícím kódu asynchronní klíčové slovo, Task
návratová hodnota, await
klíčové slovo a ToListAsync
metoda vytvoří kód asynchronně.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Klíčové
async
slovo říká kompilátoru, aby:- Vygenerujte zpětná volání pro části těla metody.
- Vytvořte vrácený objekt Task .
- Návratový
Task
typ představuje probíhající práci. - Klíčové
await
slovo způsobí, že kompilátor rozdělí metodu do dvou částí. První část končí operací, která se spouští asynchronně. Druhá část se vloží do metody zpětného volání, která se volá při dokončení operace. ToListAsync
je asynchronní verzeToList
metody rozšíření.
Při psaní asynchronního kódu, který používá EF Core:
- Asynchronně se spustí pouze příkazy, které způsobují odeslání dotazů nebo příkazů do databáze. To zahrnuje
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
aSaveChangesAsync
. Neobsahuje příkazy, které jen mění ,IQueryable
napříkladvar students = context.Students.Where(s => s.LastName == "Davolio")
. - Kontext EF Core není bezpečný pro vlákno: Nepokoušejte se paralelně provádět více operací.
- Pokud chcete využít výhod výkonu asynchronního kódu, ověřte, že balíčky knihoven (například pro stránkování) používají asynchronní, pokud volají EF Core metody, které odesílají dotazy do databáze.
Další informace o asynchronním programování v .NET naleznete v tématu Přehled asynchronního a asynchronního programování pomocí asynchronního a await.
Upozorňující
Asynchronní implementace Microsoft.Data.SqlClient obsahuje některé známé problémy (#593, #601 a další). Pokud dochází k neočekávaným problémům s výkonem, zkuste místo toho použít spuštění příkazu synchronizace, zejména při práci s velkými textovými nebo binárními hodnotami.
Důležité informace o výkonu
Obecně platí, že webová stránka by neměla načítat libovolný počet řádků. Dotaz by měl používat stránkování nebo omezený přístup. Předchozí dotaz může například použít Take
k omezení vrácených řádků:
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Výčet velké tabulky v zobrazení by mohl vrátit částečně sestavenou odpověď HTTP 200, pokud dojde k výčtu výjimky databáze.
Stránkování se zabývá později v tomto kurzu.
Další informace najdete v tématu Důležité informace o výkonu (EF).
Další kroky
Použití SQLite pro vývoj, SQL Server pro produkční prostředí
Toto je první v řadě kurzů, které ukazují, jak používat Entity Framework (EF) Core v aplikaci ASP.NET Core Razor Pages . Kurzy vytvářejí web pro fiktivní univerzitu Contoso. Web obsahuje funkce, jako je přijetí studentů, vytvoření kurzu a zadání instruktora. Tento kurz používá první přístup kódu. Informace o sledování tohoto kurzu s využitím prvního přístupu k databázi najdete v tomto problému na GitHubu.
Stáhněte nebo zobrazte dokončenou aplikaci. Pokyny ke stažení
Požadavky
- Pokud s stránkami teprve začínáteRazor, projděte si před zahájením této série kurzů Začínáme se stránkamiRazor.
- Sada Visual Studio 2019 16.8 nebo novější se sadou funkcí Vývoj pro ASP.NET a web
- Sada .NET 5.0 SDK
Databázové stroje
Pokyny pro Visual Studio používají SQL Server LocalDB, verzi SQL Serveru Express, která běží jenom ve Windows.
Řešení problému
Pokud narazíte na problém, který nemůžete vyřešit, porovnejte kód s dokončeným projektem. Dobrý způsob, jak získat pomoc, je odesláním otázky na StackOverflow.com pomocí značky ASP.NET Core nebo značkyEF Core.
Ukázková aplikace
Aplikace vytvořená v těchto kurzech je základní web pro vysokoškoláky. Uživatelé můžou zobrazit a aktualizovat informace o studentech, kurzech a instruktorech. Tady je několik obrazovek vytvořených v kurzu.
Styl uživatelského rozhraní tohoto webu je založený na předdefinovaných šablonách projektů. Tento kurz se zaměřuje na použití EF Core s ASP.NET Core, nikoli na přizpůsobení uživatelského rozhraní.
Volitelné: Sestavení ukázkového stažení
Tento krok je nepovinný. Sestavení dokončené aplikace se doporučuje, když máte problémy, které nemůžete vyřešit. Pokud narazíte na problém, který nemůžete vyřešit, porovnejte kód s dokončeným projektem. Pokyny ke stažení
Výběrem ContosoUniversity.csproj
otevřete projekt.
- Sestavte projekt.
- V konzole Správce balíčků (PMC) spusťte následující příkaz:
Update-Database
Spuštěním projektu zasadíte databázi.
Vytvoření projektu webové aplikace
- Spusťte Visual Studio a vyberte Vytvořit nový projekt.
- V dialogovém okně Vytvořit nový projekt vyberte ASP.NET Další webová aplikace>Core.
- V dialogovém okně Konfigurovat nový projekt zadejte
ContosoUniversity
název projektu. Je důležité použít tento přesný název včetně velkých písmen, takže se každý z nichnamespace
shoduje při zkopírování kódu. - Vyberte Vytvořit.
- V dialogovém okně Vytvořit novou webovou aplikaci ASP.NET Core vyberte:
- .NET Core a ASP.NET Core 5.0 v rozevíracích sadě
- ASP.NET Core Web App.
- Vytvořit
Nastavení stylu webu
Zkopírujte a vložte do Pages/Shared/_Layout.cshtml
souboru následující kód:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Soubor rozložení nastaví záhlaví webu, zápatí a nabídku. Předchozí kód provede následující změny:
- Každý výskyt "ContosoUniversity" na "Contoso University". Existují tři výskyty.
- Položky Home nabídky a Privacy položky nabídky se odstraní.
- Položky jsou přidány pro About, Students, Courses, Instructors a Departments.
Nahraďte Pages/Index.cshtml
obsah souboru následujícím kódem:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
<a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
<a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
</p>
</div>
</div>
</div>
</div>
Předchozí kód nahradí text o ASP.NET Core textem o této aplikaci.
Spuštěním aplikace ověřte, že se home zobrazí stránka.
Datový model
Následující části vytvoří datový model:
Student se může zaregistrovat do libovolného počtu kurzů a kurz může mít v něm zaregistrovaný libovolný počet studentů.
Entita Student
Ve složce projektu vytvořte složku Models .
Vytvořte
Models/Student.cs
pomocí následujícího kódu:using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Vlastnost ID
se stane sloupcem primárního klíče v tabulce databáze, která odpovídá této třídě. Ve výchozím nastavení interpretuje vlastnost, EF Core která je pojmenovaná ID
nebo classnameID
jako primární klíč. Proto je alternativou automaticky rozpoznaný název primárního Student
klíče StudentID
třídy . Další informace najdete v tématu EF Core – Klíče.
Vlastnost Enrollments
je navigační vlastnost. Vlastnosti navigace obsahují další entity, které souvisejí s touto entitou. V tomto případě Enrollments
vlastnost Student
entity obsahuje všechny Enrollment
entity, které se vztahují k tomuto studentu. Pokud má například řádek Student v databázi dva související řádky registrace, Enrollments
navigační vlastnost obsahuje tyto dvě entity registrace.
V databázi se řádek Registrace vztahuje k řádku Student, pokud jeho StudentID
sloupec obsahuje hodnotu ID studenta. Předpokládejme například, že řádek Student má ID=1. Související řádky registrace budou mít StudentID
hodnotu = 1. StudentID
je cizí klíč v tabulce Registrace.
Vlastnost je definována Enrollments
, protože ICollection<Enrollment>
může existovat více souvisejících entit registrace. Lze použít jiné typy kolekcí, například List<Enrollment>
.HashSet<Enrollment>
Při ICollection<Enrollment>
použití EF Core vytvoří kolekci HashSet<Enrollment>
ve výchozím nastavení.
Entita Registrace
Vytvořte Models/Enrollment.cs
pomocí následujícího kódu:
using System.ComponentModel.DataAnnotations;
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
[DisplayFormat(NullDisplayText = "No grade")]
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Vlastnost EnrollmentID
je primární klíč; tato entita používá classnameID
vzor místo ID
sebe sama. V případě produkčního datového modelu si mnoho vývojářů zvolí jeden vzor a konzistentně ho použije. V tomto kurzu se obě používají k ilustraci toho, že obě fungují. Použití ID
bez classname
usnadnění implementace některých druhů změn datového modelu.
Vlastnost Grade
je .enum
Otazník za Grade
deklaraci typu označuje, že Grade
vlastnost je nullable. Známka, která má hodnotu null, se liší od nulové známky – hodnota null znamená, že známka není známa nebo ještě nebyla přiřazena.
Vlastnost StudentID
je cizí klíč a odpovídající navigační vlastnost je Student
. Entita Enrollment
je přidružená k jedné Student
entitě, takže vlastnost obsahuje jednu Student
entitu.
Vlastnost CourseID
je cizí klíč a odpovídající navigační vlastnost je Course
. Entita Enrollment
je přidružená k jedné Course
entitě.
EF Core interpretuje vlastnost jako cizí klíč, pokud je pojmenovaná <navigation property name><primary key property name>
. Je to napříkladStudentID
cizí klíč pro Student
navigační vlastnost, protože Student
primární klíč entity je ID
. Vlastnosti cizího klíče lze také pojmenovat <primary key property name>
. Například vzhledem k tomu, CourseID
že Course
primární klíč entity je CourseID
.
Entita Course
Vytvořte Models/Course.cs
pomocí následujícího kódu:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Vlastnost Enrollments
je navigační vlastnost. Entita Course
může souviset s libovolným počtem Enrollment
entit.
Atribut DatabaseGenerated
umožňuje aplikaci místo vygenerování databáze zadat primární klíč.
Sestavte projekt, abyste ověřili, že nedošlo k žádným chybám kompilátoru.
Vygenerované stránky studentů
V této části se k vygenerování používá nástroj pro generování uživatelského rozhraní ASP.NET Core:
- Třída EF Core
DbContext
. Kontext je hlavní třída, která koordinuje funkce Entity Framework pro daný datový model. Odvozuje z Microsoft.EntityFrameworkCore.DbContext třídy. - Razor stránky, které zpracovávají operace vytvoření, čtení, aktualizace a odstranění (CRUD) pro entitu
Student
.
- Vytvořte složku Pages/Students .
- V Průzkumník řešení klikněte pravým tlačítkem na složku Pages/Students a vyberte Přidat>novou vygenerovanou položku.
- V dialogovém okně Přidat novou položku uživatelského rozhraní:
- Na levé kartě vyberte Nainstalované > společné >Razor stránky.
- Vyberte Razor stránky pomocí entity Framework (CRUD)>ADD.
- V dialogovém okně Přidat Razor stránky pomocí entity Framework (CRUD):
- V rozevíracím seznamu Třída modelu vyberte Student (ContosoUniversity.Models).
- V řádku třídy kontextu dat vyberte znaménko + (plus).
- Změňte název kontextu dat tak, aby končil
SchoolContext
místoContosoUniversityContext
. Aktualizovaný název kontextu:ContosoUniversity.Data.SchoolContext
- Výběrem možnosti Přidat dokončíte přidání třídy kontextu dat.
- Výběrem možnosti Přidat dokončete dialogové okno Přidat Razor stránky .
- Změňte název kontextu dat tak, aby končil
Pokud generování uživatelského rozhraní selže s chybou 'Install the package Microsoft.VisualStudio.Web.CodeGeneration.Design and try again.'
, spusťte znovu nástroj pro generování uživatelského rozhraní nebo se podívejte na tento problém na GitHubu.
Automaticky se nainstalují následující balíčky:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Microsoft.VisualStudio.Web.CodeGeneration.Design
Pokud předchozí krok selže, sestavte projekt a zopakujte krok generování.
Proces generování uživatelského rozhraní:
- Vytvoří Razor stránky ve složce Pages/Students :
Create.cshtml
aCreate.cshtml.cs
Delete.cshtml
aDelete.cshtml.cs
Details.cshtml
aDetails.cshtml.cs
Edit.cshtml
aEdit.cshtml.cs
Index.cshtml
aIndex.cshtml.cs
- Vytvoří
Data/SchoolContext.cs
. - Přidá kontext do injektáže závislostí v
Startup.cs
souboru . - Přidá databázi připojovací řetězec do
appsettings.json
.
Připojovací řetězec databáze
Nástroj pro generování uživatelského rozhraní vygeneruje v souboru připojovací řetězecappsettings.json
.
Připojovací řetězec určuje SQL Server LocalDB:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=CU-1;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB je zjednodušená verze databázového stroje SQL Server Express a je určená pro vývoj aplikací, nikoli pro produkční použití. Ve výchozím nastavení LocalDB vytvoří .mdf soubory v C:/Users/<user>
adresáři.
Aktualizace třídy kontextu databáze
Hlavní třída, která koordinuje EF Core funkce pro daný datový model, je třída kontextu databáze. Kontext je odvozen z Microsoft.EntityFrameworkCore.DbContext. Kontext určuje, které entity jsou součástí datového modelu. V tomto projektu má třída název SchoolContext
.
Aktualizujte Data/SchoolContext.cs
následujícím kódem:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Předchozí kód se změní z jednotného čísla DbSet<Student> Student
na množné číslo DbSet<Student> Students
. Pokud chcete, aby Razor kód Stránky odpovídal novému DBSet
názvu, proveďte globální změnu z: _context.Student.
k: _context.Students.
Existuje 8 výskytů.
Vzhledem k tomu, že sada entit obsahuje více entit, mnoho vývojářů dává přednost DBSet
názvům vlastností v množném čísle.
Zvýrazněný kód:
- Vytvoří DbSet<TEntity> vlastnost pro každou sadu entit. V EF Core terminologii:
- Sada entit obvykle odpovídá databázové tabulce.
- Entita odpovídá řádku v tabulce.
- Zavolá metodu OnModelCreating.
OnModelCreating
:- Volá se, když
SchoolContext
byl inicializován, ale před tím, než byl model zabezpečen a použit k inicializaci kontextu. - Je vyžadováno, protože v pozdější části kurzu
Student
bude mít entita odkazy na ostatní entity.
- Volá se, když
Sestavte projekt, abyste ověřili, že nedošlo k žádným chybám kompilátoru.
Startup.cs
ASP.NET Core se sestavuje pomocí injektáže závislostí. Služby, jako SchoolContext
je například injektáž závislostí, se registrují během spuštění aplikace. 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.
Nástroj pro generování uživatelského rozhraní automaticky zaregistroval třídu kontextu s kontejnerem injektáže závislostí.
Následující zvýrazněné řádky přidal scaffolder:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
}
Název připojovací řetězec se předává kontextu voláním metody na objektuDbContextOptions. V případě místního vývoje načte konfigurační systém ASP.NET Core připojovací řetězec ze appsettings.json
souboru.
Přidání filtru výjimek databáze
Přidejte AddDatabaseDeveloperPageExceptionFilter a UseMigrationsEndPoint jak je znázorněno v následujícím kódu:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
services.AddDatabaseDeveloperPageExceptionFilter();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Přidejte balíček NuGet Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.
V konzole Správce balíčků zadejte následující příkaz, který přidá balíček NuGet:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Balíček Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
NuGet poskytuje ASP.NET middlewaru Core pro chybové stránky Entity Framework Core. Tento middleware pomáhá zjišťovat a diagnostikovat chyby při migracích Entity Framework Core.
Poskytuje AddDatabaseDeveloperPageExceptionFilter
užitečné informace o chybách chyb ve vývojovém prostředí pro chyby migrace EF.
Vytvoření databáze
Aktualizujte Program.cs
databázi, pokud neexistuje:
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
CreateDbIfNotExists(host);
host.Run();
}
private static void CreateDbIfNotExists(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Metoda EnsureCreated neprobíná žádnou akci, pokud existuje databáze pro kontext. Pokud žádná databáze neexistuje, vytvoří databázi a schéma. EnsureCreated
umožňuje následující pracovní postup pro zpracování změn datového modelu:
- Odstraňte databázi. Všechna existující data se ztratí.
- Změňte datový model. Můžete například přidat
EmailAddress
pole. - Spustit aplikaci.
EnsureCreated
vytvoří databázi s novým schématem.
Tento pracovní postup funguje v rané fázi vývoje, když se schéma rychle vyvíjí, pokud data nemusí být zachována. Situace se liší, když je potřeba zachovat data zadaná do databáze. V takovém případě použijte migrace.
Později v sérii kurzů se databáze odstraní, kterou vytvořila EnsureCreated
a migrace se použije. Databázi vytvořenou pomocí EnsureCreated
migrací nejde aktualizovat.
Otestování aplikace
- Spustit aplikaci.
- Vyberte odkaz Studenti a pak vytvořte nový.
- Otestujte odkazy Upravit, Podrobnosti a Odstranit.
Počáteční hodnota databáze
Metoda EnsureCreated
vytvoří prázdnou databázi. Tato část přidá kód, který naplní databázi testovacími daty.
Vytvořte Data/DbInitializer.cs
pomocí následujícího kódu:
using ContosoUniversity.Models;
using System;
using System.Linq;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kód zkontroluje, jestli v databázi nejsou žádní studenti. Pokud nejsou žádní studenti, přidá do databáze testovací data. Vytvoří testovací data v polích místo List<T>
kolekcí pro optimalizaci výkonu.
V
Program.cs
, odebrat//
zDbInitializer.Initialize
řádku:context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Pokud je aplikace spuštěná, zastavte ji a v konzole Správce balíčků (PMC) spusťte následující příkaz:
Drop-Database -Confirm
Odpovězte na
Y
odstranění databáze.
- Restartujte aplikaci.
- Výběrem stránky Studenti zobrazíte počáteční data.
Zobrazení databáze
- V nabídce Zobrazit v sadě Visual Studio otevřete SQL Server Průzkumník objektů (SSOX).
- V nástroji SSOX vyberte (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Název databáze se vygeneruje z názvu kontextu, který jste zadali dříve, a navíc pomlčku a identifikátor GUID.
- Rozbalte uzel Tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit data zobrazte sloupce vytvořené a řádky vložené do tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit kód zobrazte, jak se
Student
model mapuje naStudent
schéma tabulky.
Asynchronní kód
Asynchronní programování je výchozí režim pro ASP.NET Core a EF Core.
Webový server má k dispozici omezený počet vláken a v situacích s vysokým zatížením se můžou používat všechna dostupná vlákna. V takovém případě nemůže server zpracovat nové požadavky, dokud se vlákna nevysadí. V synchronním kódu může být mnoho vláken svázané, zatímco nefungují, protože čekají na dokončení vstupně-výstupních operací. Když proces čeká na dokončení vstupně-výstupních operací, v asynchronním kódu se jeho vlákno uvolní, aby server používal ke zpracování dalších požadavků. V důsledku toho asynchronní kód umožňuje efektivnější použití serverových prostředků a server dokáže zpracovat větší provoz bez zpoždění.
Asynchronní kód zavádí v době běhu malé režijní náklady. U situací s nízkým provozem je dosažení výkonu zanedbatelné, zatímco u vysokých dopravních situací je potenciální zlepšení výkonu podstatné.
V následujícím kódu asynchronní klíčové slovo, Task
návratová hodnota, await
klíčové slovo a ToListAsync
metoda vytvoří kód asynchronně.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Klíčové
async
slovo říká kompilátoru, aby:- Vygenerujte zpětná volání pro části těla metody.
- Vytvořte vrácený objekt Task .
- Návratový
Task
typ představuje probíhající práci. - Klíčové
await
slovo způsobí, že kompilátor rozdělí metodu do dvou částí. První část končí operací, která se spouští asynchronně. Druhá část se vloží do metody zpětného volání, která se volá při dokončení operace. ToListAsync
je asynchronní verzeToList
metody rozšíření.
Při psaní asynchronního kódu, který používá EF Core:
- Asynchronně se spustí pouze příkazy, které způsobují odeslání dotazů nebo příkazů do databáze. To zahrnuje
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
aSaveChangesAsync
. Neobsahuje příkazy, které jen mění ,IQueryable
napříkladvar students = context.Students.Where(s => s.LastName == "Davolio")
. - Kontext EF Core není bezpečný pro vlákno: Nepokoušejte se paralelně provádět více operací.
- Pokud chcete využít výhod výkonu asynchronního kódu, ověřte, že balíčky knihoven (například pro stránkování) používají asynchronní, pokud volají EF Core metody, které odesílají dotazy do databáze.
Další informace o asynchronním programování v .NET naleznete v tématu Přehled asynchronního a asynchronního programování pomocí asynchronního a await.
Důležité informace o výkonu
Obecně platí, že webová stránka by neměla načítat libovolný počet řádků. Dotaz by měl používat stránkování nebo omezený přístup. Předchozí dotaz může například použít Take
k omezení vrácených řádků:
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Výčet velké tabulky v zobrazení by mohl vrátit částečně sestavenou odpověď HTTP 200, pokud dojde k výčtu výjimky databáze.
MaxModelBindingCollectionSize výchozí hodnota je 1024. Následující sady MaxModelBindingCollectionSize
kódu:
public void ConfigureServices(IServiceCollection services)
{
var myMaxModelBindingCollectionSize = Convert.ToInt32(
Configuration["MyMaxModelBindingCollectionSize"] ?? "100");
services.Configure<MvcOptions>(options =>
options.MaxModelBindingCollectionSize = myMaxModelBindingCollectionSize);
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
services.AddDatabaseDeveloperPageExceptionFilter();
}
Informace o nastavení konfigurace, jako je MyMaxModelBindingCollectionSize
.
Stránkování se zabývá později v tomto kurzu.
Další informace najdete v tématu Důležité informace o výkonu (EF).
Protokolování SQL entity Framework Core
Konfiguraci protokolování obvykle zajišťuje oddíl Logging
souborů appsettings.{Environment}.json
. Pokud chcete protokolovat příkazy SQL, přidejte "Microsoft.EntityFrameworkCore.Database.Command": "Information"
do appsettings.Development.json
souboru:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyDB-2;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
,"Microsoft.EntityFrameworkCore.Database.Command": "Information"
}
},
"AllowedHosts": "*"
}
V předchozím kódu JSON se příkazy SQL zobrazí na příkazovém řádku a v okně výstupu sady Visual Studio.
Další informace najdete v tématu Protokolování v .NET Core a ASP.NET Core a tento problém na GitHubu.
Další kroky
Použití SQLite pro vývoj, SQL Server pro produkční prostředí
Toto je první v řadě kurzů, které ukazují, jak používat Entity Framework (EF) Core v aplikaci ASP.NET Core Razor Pages . Kurzy vytvářejí web pro fiktivní univerzitu Contoso. Web obsahuje funkce, jako je přijetí studentů, vytvoření kurzu a zadání instruktora. Tento kurz používá první přístup kódu. Informace o sledování tohoto kurzu s využitím prvního přístupu k databázi najdete v tomto problému na GitHubu.
Stáhněte nebo zobrazte dokončenou aplikaci. Pokyny ke stažení
Požadavky
- Pokud s stránkami teprve začínáteRazor, projděte si před zahájením této série kurzů Začínáme se stránkamiRazor.
- Visual Studio 2019 s úlohou vývoje pro ASP.NET a web
- .NET Core 3.0 SDK
Databázové stroje
Pokyny pro Visual Studio používají SQL Server LocalDB, verzi SQL Serveru Express, která běží jenom ve Windows.
Pokyny pro Visual Studio Code používají SQLite, databázový stroj pro různé platformy.
Pokud se rozhodnete používat SQLite, stáhněte a nainstalujte nástroj třetí strany pro správu a zobrazení databáze SQLite, například prohlížeč databáze pro SQLite.
Řešení problému
Pokud narazíte na problém, který nemůžete vyřešit, porovnejte kód s dokončeným projektem. Dobrý způsob, jak získat pomoc, je odesláním otázky na StackOverflow.com pomocí značky ASP.NET Core nebo značkyEF Core.
Ukázková aplikace
Aplikace vytvořená v těchto kurzech je základní web pro vysokoškoláky. Uživatelé můžou zobrazit a aktualizovat informace o studentech, kurzech a instruktorech. Tady je několik obrazovek vytvořených v kurzu.
Styl uživatelského rozhraní tohoto webu je založený na předdefinovaných šablonách projektů. Tento kurz se zaměřuje na to, jak používat EF Core, nikoli jak přizpůsobit uživatelské rozhraní.
Pokud chcete získat zdrojový kód dokončeného projektu, postupujte podle odkazu v horní části stránky. Složka cu30 obsahuje kód pro verzi kurzu ASP.NET Core 3.0. Soubory, které odrážejí stav kódu pro kurzy 1-7, najdete ve složce cu30snapshots .
Spuštění aplikace po stažení dokončeného projektu:
Sestavte projekt.
V konzole Správce balíčků (PMC) spusťte následující příkaz:
Update-Database
Spuštěním projektu zasadíte databázi.
Vytvoření projektu webové aplikace
- V nabídce Soubor sady Visual Studio vyberte Nový>projekt.
- Vyberte ASP.NET Základní webová aplikace.
- Pojmenujte projekt ContosoUniversity. Je důležité použít tento přesný název včetně velkých písmen, aby se obory názvů při kopírování a vkládání kódu shodovaly.
- V rozevíracích sadě vyberte .NET Core a ASP.NET Core 3.0 a pak vyberte Webová aplikace.
Nastavení stylu webu
Nastavení záhlaví, zápatí webu a nabídky aktualizací Pages/Shared/_Layout.cshtml
:
Změňte každý výskyt "ContosoUniversity" na "Contoso University". Existují tři výskyty.
Home Odstraňte položky a Privacy položky nabídky a přidejte položky pro informace, studenty, kurzy, instruktory a oddělení.
Změny jsou zvýrazněné.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Contoso University</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Nahraďte Pages/Index.cshtml
obsah souboru následujícím kódem, který nahradí text o ASP.NET Core textem o této aplikaci:
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="row mb-auto">
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 mb-4 ">
<p class="card-text">
Contoso University is a sample application that
demonstrates how to use Entity Framework Core in an
ASP.NET Core Razor Pages web app.
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column position-static">
<p class="card-text mb-auto">
You can build the application by following the steps in a series of tutorials.
</p>
<p>
<a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row no-gutters border mb-4">
<div class="col p-4 d-flex flex-column">
<p class="card-text mb-auto">
You can download the completed project from GitHub.
</p>
<p>
<a href="https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
</p>
</div>
</div>
</div>
</div>
Spuštěním aplikace ověřte, že se home zobrazí stránka.
Datový model
Následující části vytvoří datový model:
Student se může zaregistrovat do libovolného počtu kurzů a kurz může mít v něm zaregistrovaný libovolný počet studentů.
Entita Student
Ve složce projektu vytvořte složku Models .
Vytvořte
Models/Student.cs
pomocí následujícího kódu:using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } } }
Vlastnost ID
se stane sloupcem primárního klíče v tabulce databáze, která odpovídá této třídě. Ve výchozím nastavení interpretuje vlastnost, EF Core která je pojmenovaná ID
nebo classnameID
jako primární klíč. Proto je alternativou automaticky rozpoznaný název primárního Student
klíče StudentID
třídy . Další informace najdete v tématu EF Core – Klíče.
Vlastnost Enrollments
je navigační vlastnost. Vlastnosti navigace obsahují další entity, které souvisejí s touto entitou. V tomto případě Enrollments
vlastnost Student
entity obsahuje všechny Enrollment
entity, které se vztahují k tomuto studentu. Pokud má například řádek Student v databázi dva související řádky registrace, Enrollments
navigační vlastnost obsahuje tyto dvě entity registrace.
V databázi se řádek Registrace vztahuje k řádku Student, pokud jeho sloupec StudentID obsahuje hodnotu ID studenta. Předpokládejme například, že řádek Student má ID=1. Související řádky registrace budou mít ID studenta = 1. ID studenta je cizí klíč v tabulce Registrace.
Vlastnost je definována Enrollments
, protože ICollection<Enrollment>
může existovat více souvisejících entit registrace. Můžete použít jiné typy kolekcí, například List<Enrollment>
nebo HashSet<Enrollment>
. Při ICollection<Enrollment>
použití EF Core vytvoří kolekci HashSet<Enrollment>
ve výchozím nastavení.
Entita Registrace
Vytvořte Models/Enrollment.cs
pomocí následujícího kódu:
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public Course Course { get; set; }
public Student Student { get; set; }
}
}
Vlastnost EnrollmentID
je primární klíč; tato entita používá classnameID
vzor místo ID
sebe sama. Pro produkční datový model zvolte jeden vzor a používejte ho konzistentně. V tomto kurzu se obě používají k ilustraci toho, že obě fungují. Použití ID
bez classname
usnadnění implementace některých druhů změn datového modelu.
Vlastnost Grade
je .enum
Otazník za Grade
deklaraci typu označuje, že Grade
vlastnost je nullable. Známka, která má hodnotu null, se liší od nulové známky – hodnota null znamená, že známka není známa nebo ještě nebyla přiřazena.
Vlastnost StudentID
je cizí klíč a odpovídající navigační vlastnost je Student
. Entita Enrollment
je přidružená k jedné Student
entitě, takže vlastnost obsahuje jednu Student
entitu.
Vlastnost CourseID
je cizí klíč a odpovídající navigační vlastnost je Course
. Entita Enrollment
je přidružená k jedné Course
entitě.
EF Core interpretuje vlastnost jako cizí klíč, pokud je pojmenovaná <navigation property name><primary key property name>
. Je to napříkladStudentID
cizí klíč pro Student
navigační vlastnost, protože Student
primární klíč entity je ID
. Vlastnosti cizího klíče lze také pojmenovat <primary key property name>
. Například vzhledem k tomu, CourseID
že Course
primární klíč entity je CourseID
.
Entita Course
Vytvořte Models/Course.cs
pomocí následujícího kódu:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
}
Vlastnost Enrollments
je navigační vlastnost. Entita Course
může souviset s libovolným počtem Enrollment
entit.
Atribut DatabaseGenerated
umožňuje aplikaci místo vygenerování databáze zadat primární klíč.
Sestavte projekt, abyste ověřili, že nedošlo k žádným chybám kompilátoru.
Vygenerované stránky studentů
V této části použijete nástroj pro generování uživatelského rozhraní ASP.NET Core:
- Třída EF Corekontextu . Kontext je hlavní třída, která koordinuje funkce Entity Framework pro daný datový model. Odvozuje z
Microsoft.EntityFrameworkCore.DbContext
třídy. - Razor stránky, které zpracovávají operace vytvoření, čtení, aktualizace a odstranění (CRUD) pro entitu
Student
.
- Ve složce Pages vytvořte složku Students.
- V Průzkumník řešení klikněte pravým tlačítkem na složku Pages/Students a vyberte Přidat>novou vygenerovanou položku.
- V dialogovém okně Přidat generování uživatelského rozhraní vyberte Razor Stránky pomocí entity Framework (CRUD)>ADD.
- V dialogovém okně Přidat Razor stránky pomocí entity Framework (CRUD):
- V rozevíracím seznamu Třída modelu vyberte Student (ContosoUniversity.Models).
- V řádku třídy kontextu dat vyberte znaménko + (plus).
- Změňte název kontextu dat z ContosoUniversity.Models.ContosoUniversityContext na ContosoUniversity.Data.SchoolContext.
- Vyberte Přidat.
Automaticky se nainstalují následující balíčky:
Microsoft.VisualStudio.Web.CodeGeneration.Design
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.Extensions.Logging.Debug
Microsoft.EntityFrameworkCore.Tools
Pokud máte potíže s předchozím krokem, sestavte projekt a zopakujte krok generování.
Proces generování uživatelského rozhraní:
- Vytvoří Razor stránky ve složce Pages/Students :
Create.cshtml
aCreate.cshtml.cs
Delete.cshtml
aDelete.cshtml.cs
Details.cshtml
aDetails.cshtml.cs
Edit.cshtml
aEdit.cshtml.cs
Index.cshtml
aIndex.cshtml.cs
- Vytvoří
Data/SchoolContext.cs
. - Přidá kontext do injektáže závislostí v
Startup.cs
souboru . - Přidá databázi připojovací řetězec do
appsettings.json
.
Připojovací řetězec databáze
Soubor appsettings.json
určuje připojovací řetězec SQL Server LocalDB.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext6;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB je zjednodušená verze databázového stroje SQL Server Express a je určená pro vývoj aplikací, nikoli pro produkční použití. Ve výchozím nastavení LocalDB vytvoří .mdf soubory v C:/Users/<user>
adresáři.
Aktualizace třídy kontextu databáze
Hlavní třída, která koordinuje EF Core funkce pro daný datový model, je třída kontextu databáze. Kontext je odvozen z Microsoft.EntityFrameworkCore.DbContext. Kontext určuje, které entity jsou součástí datového modelu. V tomto projektu má třída název SchoolContext
.
Aktualizujte Data/SchoolContext.cs
následujícím kódem:
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
namespace ContosoUniversity.Data
{
public class SchoolContext : DbContext
{
public SchoolContext (DbContextOptions<SchoolContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
modelBuilder.Entity<Student>().ToTable("Student");
}
}
}
Zvýrazněný kód vytvoří DbSet<TEntity> vlastnost pro každou sadu entit. V EF Core terminologii:
- Sada entit obvykle odpovídá databázové tabulce.
- Entita odpovídá řádku v tabulce.
Vzhledem k tomu, že sada entit obsahuje více entit, vlastnosti DBSet by měly být názvy množného čísla. Vzhledem k tomu, že nástroj pro generování uživatelského rozhraní vytvořilStudent
sadu DBSet, tento krok ho změní na množné číslo Students
.
Pokud chcete, aby Razor kód Pages odpovídal novému názvu dbSet, proveďte globální změnu v celém projektu _context.Student
na _context.Students
. Existuje 8 výskytů.
Sestavte projekt, abyste ověřili, že nedošlo k žádným chybám kompilátoru.
Startup.cs
ASP.NET Core se sestavuje pomocí injektáže závislostí. Služby (například EF Core kontext databáze) se během spouštění aplikace registrují pomocí injektáže závislostí. Komponenty, které vyžadují tyto služby (například Razor stránky), jsou tyto služby poskytovány prostřednictvím parametrů konstruktoru. Kód konstruktoru, který získá instanci kontextu databáze, se zobrazí později v kurzu.
Nástroj pro generování uživatelského rozhraní automaticky zaregistroval třídu kontextu s kontejnerem injektáže závislostí.
V
ConfigureServices
, zvýrazněné čáry byly přidány scaffolder:public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SchoolContext"))); }
Název připojovací řetězec se předává kontextu voláním metody na objektuDbContextOptions. V případě místního vývoje načte konfigurační systém ASP.NET Core připojovací řetězec ze appsettings.json
souboru.
Vytvoření databáze
Aktualizujte Program.cs
databázi, pokud neexistuje:
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
CreateDbIfNotExists(host);
host.Run();
}
private static void CreateDbIfNotExists(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
Metoda EnsureCreated neprobíná žádnou akci, pokud existuje databáze pro kontext. Pokud žádná databáze neexistuje, vytvoří databázi a schéma. EnsureCreated
umožňuje následující pracovní postup pro zpracování změn datového modelu:
- Odstraňte databázi. Všechna existující data se ztratí.
- Změňte datový model. Můžete například přidat
EmailAddress
pole. - Spustit aplikaci.
EnsureCreated
vytvoří databázi s novým schématem.
Tento pracovní postup funguje dobře v rané fázi vývoje, pokud se schéma rychle vyvíjí, pokud nepotřebujete zachovat data. Situace se liší, když je potřeba zachovat data zadaná do databáze. V takovém případě použijte migrace.
Později v sérii kurzů odstraníte databázi, kterou jste vytvořili EnsureCreated
, a místo toho použijete migrace. Databázi vytvořenou pomocí EnsureCreated
migrací nejde aktualizovat.
Otestování aplikace
- Spustit aplikaci.
- Vyberte odkaz Studenti a pak vytvořte nový.
- Otestujte odkazy Upravit, Podrobnosti a Odstranit.
Počáteční hodnota databáze
Metoda EnsureCreated
vytvoří prázdnou databázi. Tato část přidá kód, který naplní databázi testovacími daty.
Vytvořte Data/DbInitializer.cs
pomocí následujícího kódu:
using ContosoUniversity.Data;
using ContosoUniversity.Models;
using System;
using System.Linq;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
context.Database.EnsureCreated();
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
var courses = new Course[]
{
new Course{CourseID=1050,Title="Chemistry",Credits=3},
new Course{CourseID=4022,Title="Microeconomics",Credits=3},
new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
new Course{CourseID=1045,Title="Calculus",Credits=4},
new Course{CourseID=3141,Title="Trigonometry",Credits=4},
new Course{CourseID=2021,Title="Composition",Credits=3},
new Course{CourseID=2042,Title="Literature",Credits=4}
};
context.Courses.AddRange(courses);
context.SaveChanges();
var enrollments = new Enrollment[]
{
new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
new Enrollment{StudentID=3,CourseID=1050},
new Enrollment{StudentID=4,CourseID=1050},
new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
new Enrollment{StudentID=6,CourseID=1045},
new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
};
context.Enrollments.AddRange(enrollments);
context.SaveChanges();
}
}
}
Kód zkontroluje, jestli v databázi nejsou žádní studenti. Pokud nejsou žádní studenti, přidá do databáze testovací data. Vytvoří testovací data v polích místo List<T>
kolekcí pro optimalizaci výkonu.
V
Program.cs
části , nahraďteEnsureCreated
hovor volánímDbInitializer.Initialize
:// context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Pokud je aplikace spuštěná, zastavte ji a v konzole Správce balíčků (PMC) spusťte následující příkaz:
Drop-Database
Restartujte aplikaci.
Výběrem stránky Studenti zobrazíte počáteční data.
Zobrazení databáze
- V nabídce Zobrazit v sadě Visual Studio otevřete SQL Server Průzkumník objektů (SSOX).
- V nástroji SSOX vyberte (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Název databáze se vygeneruje z názvu kontextu, který jste zadali dříve a pomlčku a identifikátor GUID.
- Rozbalte uzel Tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit data zobrazte sloupce vytvořené a řádky vložené do tabulky.
- Klikněte pravým tlačítkem myši na tabulku Student a kliknutím na Zobrazit kód zobrazte, jak se
Student
model mapuje naStudent
schéma tabulky.
Asynchronní kód
Asynchronní programování je výchozí režim pro ASP.NET Core a EF Core.
Webový server má k dispozici omezený počet vláken a v situacích s vysokým zatížením se můžou používat všechna dostupná vlákna. V takovém případě nemůže server zpracovat nové požadavky, dokud se vlákna nevysadí. V synchronním kódu může být mnoho vláken svázané, zatímco ve skutečnosti neprovádí žádnou práci, protože čekají na dokončení vstupně-výstupních operací. Když proces čeká na dokončení vstupně-výstupních operací, v asynchronním kódu se jeho vlákno uvolní, aby server používal ke zpracování dalších požadavků. V důsledku toho asynchronní kód umožňuje efektivnější použití serverových prostředků a server dokáže zpracovat větší provoz bez zpoždění.
Asynchronní kód zavádí v době běhu malé režijní náklady. U situací s nízkým provozem je dosažení výkonu zanedbatelné, zatímco u vysokých dopravních situací je potenciální zlepšení výkonu podstatné.
V následujícím kódu asynchronní klíčové slovo, Task<T>
návratová hodnota, await
klíčové slovo a ToListAsync
metoda vytvoří kód asynchronně.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
- Klíčové
async
slovo říká kompilátoru, aby:- Vygenerujte zpětná volání pro části těla metody.
- Vytvořte vrácený objekt Task .
- Návratový
Task<T>
typ představuje probíhající práci. - Klíčové
await
slovo způsobí, že kompilátor rozdělí metodu do dvou částí. První část končí operací, která se spouští asynchronně. Druhá část se vloží do metody zpětného volání, která se volá při dokončení operace. ToListAsync
je asynchronní verzeToList
metody rozšíření.
Při psaní asynchronního kódu, který používá EF Core:
- Asynchronně se spustí pouze příkazy, které způsobují odeslání dotazů nebo příkazů do databáze. To zahrnuje
ToListAsync
,SingleOrDefaultAsync
,FirstOrDefaultAsync
aSaveChangesAsync
. Neobsahuje příkazy, které jen mění ,IQueryable
napříkladvar students = context.Students.Where(s => s.LastName == "Davolio")
. - Kontext EF Core není bezpečný pro vlákno: Nepokoušejte se paralelně provádět více operací.
- Pokud chcete využít výhod výkonu asynchronního kódu, ověřte, že balíčky knihoven (například pro stránkování) používají asynchronní, pokud volají EF Core metody, které odesílají dotazy do databáze.
Další informace o asynchronním programování v .NET naleznete v tématu Přehled asynchronního a asynchronního programování pomocí asynchronního a await.