Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Note
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Warning
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Tom Dykstra, Jeremy Likness ve Jon P Smith tarafından
Bu, ASP.NET Core Razor Pages uygulamasında Entity Framework (EF) Core'un nasıl kullanılacağını gösteren bir dizi öğreticinin ilkidir. Bu öğretici içerikler, kurgusal Contoso Üniversitesi için bir web sitesi oluşturmanızı sağlar. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Bu öğreticide kod öncelikli yaklaşım kullanılır. Bu öğreticiyi önce veritabanı yaklaşımını kullanarak izlemekle ilgili bilgi için bu Github sorununa bakın.
Tamamlanan uygulamayı indirin veya görüntüleyin.İndirme yönergeleri.
Prerequisites
- Razor Pages kullanmaya yeni başladıysanız, buna başlamadan önce Razor Pages ile çalışmaya başlama eğitim serisini gözden geçirin.
Visual Studio 2022 ile ASP.NET ve web geliştirme iş yükü.
Veritabanı altyapıları
Visual Studio yönergelerinde, SQL Server Express'in yalnızca Windows üzerinde çalışan bir sürümü olan SQL Server LocalDB kullanılır.
Troubleshooting
Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu da StackOverflow.com'da, ASP.NET Core etiketini veya EF Core etiketini kullanarak bir soru sormaktır.
Örnek uygulama
Bu eğitimlerde oluşturulan uygulama, basit bir üniversite web sitesidir. Kullanıcılar öğrenci, kurs ve eğitmen bilgilerini görüntüleyebilir ve güncelleştirebilir. Öğreticide oluşturulan ekranlardan birkaçı aşağıdadır.
Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Bu öğretici, kullanıcı arabirimini nasıl özelleştireceğinize değil, EF Core ASP.NET Core ile nasıl kullanacağınıza odaklanır.
İsteğe bağlı: Örnek indirme paketini oluşturun
Bu adım isteğe bağlıdır. Çözemediğiniz sorunlarla karşılaştığınızda, uygulamanın tamamlanmış sürümünü derlemeniz önerilir. Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. İndirme yönergeleri.
Projeyi açmak için seçin ContosoUniversity.csproj .
Projeyi derleyin.
Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Update-Database
Veritabanının tohumunu oluşturmak için projeyi çalıştırın.
Web uygulaması projesi oluşturma
Visual Studio 2022'yi başlatın ve Yeni proje oluştur'u seçin.
Yeni proje oluştur iletişim kutusunda ASP.NET Core Web App'i ve ardından İleri'yi seçin.
Yeni projenizi yapılandırın iletişim kutusunda, Proje adı için
ContosoUniversitygirin. Projeyi contosoUniversity olarak adlandırmak, büyük harfle eşleştirme de dahil olmak üzere önemlidir, bu nedenle örnek kodu kopyalayıp yapıştırdığınızda ad alanları eşleşecektir.sonrakiseçin.
Ek bilgi iletişim kutusunda .NET 6.0 (uzun süreli destek) öğesini ve ardından Oluştur'u seçin.
Site stilini ayarlama
Aşağıdaki kodu kopyalayıp dosyaya yapıştırın Pages/Shared/_Layout.cshtml :
<!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>
Düzen dosyası site üst bilgisini, alt bilgisini ve menüsünü ayarlar. Yukarıdaki kod aşağıdaki değişiklikleri yapar:
- "ContosoUniversity" ifadesinin geçtiği her yeri "Contoso University" olarak değiştirin. Üç örneği var.
- Home ve Privacy menü girdileri silinir.
- Hakkında, Öğrenciler, Kurslar, Eğitmenler ve Bölümler için girişler eklenir.
içinde Pages/Index.cshtmldosyasının içeriğini aşağıdaki kodla değiştirin:
@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>
Yukarıdaki kod, ASP.NET Core hakkındaki metni bu uygulamayla ilgili metinle değiştirir.
Giriş sayfasının göründüğünü doğrulamak için uygulamayı çalıştırın.
Veri modeli
Aşağıdaki bölümlerde bir veri modeli oluşturulur:
Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.
Student varlığı
- Proje klasöründe bir Models klasörü oluşturun.
- Aşağıdaki kodla oluşturun
Models/Student.cs: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; } } }
özelliği, ID veritabanı tablosunun bu sınıfa karşılık gelen birincil anahtar sütunu olur. Varsayılan olarak, EF Core veya ID adlı classnameID bir özelliği birincil anahtar olarak yorumlar. Dolayısıyla, Student sınıfının birincil anahtarı için otomatik olarak tanınan alternatif ad StudentID olur. Daha fazla bilgi için bkz EF Core . - Anahtarlar.
Enrollments özelliği bir gezinti özelliğidir. Gezinme özellikleri, bu varlıkla ilişkili diğer varlıkları içerir. Bu durumda, bir Enrollments varlığın Student özelliği o Öğrenci ile ilgili tüm Enrollment varlıkları barındırır. Örneğin, veritabanındaki bir Öğrenci satırında ilişkili iki Kayıt satırı varsa, Enrollments gezinti özelliği bu iki Kayıt varlığını içerir.
Veritabanında, bir Kayıt satırı, StudentID sütunu öğrencinin kimlik numarasını içeriyorsa bir Öğrenci satırıyla ilişkilidir. Örneğin, Bir Öğrenci satırının ID=1 olduğunu varsayalım. İlgili kayıt satırlarında StudentID = 1 olur.
StudentID Kayıt tablosundaki bir yabancı anahtardır .
Birden çok ilişkili Kayıt varlığı olabileceğinden, Enrollments özelliği ICollection<Enrollment> olarak tanımlanır. veya List<Enrollment>gibi HashSet<Enrollment> diğer koleksiyon türleri kullanılabilir. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.
Kaydolma varlığı
Aşağıdaki kodla oluşturun Models/Enrollment.cs :
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; }
}
}
EnrollmentID özelliği birincil anahtardır; bu varlıkta tek başına ID yerine classnameID deseni kullanılır. Bir üretim veri modeli için birçok geliştirici tek bir desen seçer ve bunu tutarlı bir şekilde kullanır. Bu öğreticide her ikisinin de çalıştığını göstermek için her ikisi de kullanılır. olmadan IDclassname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.
Grade özelliği bir enum'dir.
Grade tür bildiriminden sonraki soru işareti, Grade özelliğinin boş değer atanabilir olduğunu gösterir. Null olan bir not sıfırdan farklıdır; null, not bilinmediği veya henüz atanmadığı anlamına gelir.
StudentID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirStudent. Bir Enrollment varlık tek bir Student varlıkla ilişkilendirildiğinden özelliği tek Student bir varlık içerir.
CourseID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirCourse. Bir Enrollment varlık bir Course varlıkla ilişkilendirilir.
EF Core, adı <navigation property name><primary key property name> olan bir özelliği yabancı anahtar olarak yorumlar. Örneğin,StudentID varlığın birincil anahtarı Student olduğundan gezinti özelliğinin Student yabancı anahtarıdır ID. Yabancı anahtar özellikleri ayrıca <primary key property name> olarak adlandırılabilir. Örneğin, Course varlığının birincil anahtarı CourseID olduğundan CourseID.
Kurs varlığı
Aşağıdaki kodla oluşturun Models/Course.cs :
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; }
}
}
Enrollments özelliği bir gezinti özelliğidir. Bir Course varlık, herhangi bir sayıda Enrollment varlıkla ilişkilendirilebilir.
DatabaseGenerated özniteliği, veritabanının bunu oluşturması yerine uygulamanın birincil anahtarı belirtmesine olanak tanır.
Uygulamayı oluşturun. Derleyici, değerlerin nasıl null işleneceğini gösteren birkaç uyarı oluşturur. Daha fazla bilgi için bu GitHub sorununa, Null atanabilir başvuru türlerine ve Öğretici: Null atanabilir ve null atanamaz başvuru türleriyle tasarım amacınızı daha açık ifade edin konularına bakın.
Null atanabilir başvuru türlerinden kaynaklanan uyarıları ortadan kaldırmak için aşağıdaki satırı ContosoUniversity.csproj dosyasından kaldırın:
<Nullable>enable</Nullable>
Scaffolding altyapısı şu anda boş değer atanabilir başvuru türlerini desteklemediğinden, scaffold işleminde kullanılan modeller de bunları destekleyemez.
Projenin derleyici uyarıları olmadan derlenmesi için, Pages/Error.cshtml.cs içindeki public string? RequestId { get; set; } öğesinden ? null atanabilir başvuru tipi ek açıklamasını kaldırın.
Öğrenci sayfalarını yapılandır
Bu bölümde, ASP.NET Core iskele aracı şunları oluşturmak için kullanılır:
- Bir EF Core
DbContextsınıf. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır. Microsoft.EntityFrameworkCore.DbContext sınıfından türetilir. -
Razor varlık için
StudentOluşturma, Okuma, Güncelleştirme ve Silme (CRUD) işlemlerini işleyen sayfalar.
- Sayfalar/Öğrenciler klasörü oluşturun.
- Çözüm Gezgini'nde Pages/Students klasörüne sağ tıklayın ve Ekle>Yeni İskeletlenmiş Öğe'yi seçin.
-
Yeni İskele Öğesi Ekle iletişim kutusunda:
- Sol sekmede Yüklü > Ortak >Razor Sayfaları seçin
- RazorEntity Framework (CRUD) kullanan Sayfalar>ADD seçin.
-
Entity Framework Kullanarak Sayfa Ekleme (CRUD) iletişim kutusunda:
- Model class açılır listesinde Student (ContosoUniversity.Models) seçeneğini belirleyin.
-
Veri bağlamı sınıf satırında (artı) işaretini seçin + .
- Veri bağlamı adını
ContosoUniversityContextyerineSchoolContextile bitecek şekilde değiştirin. Güncelleştirilmiş bağlam adı:ContosoUniversity.Data.SchoolContext - Veri bağlamı sınıfını eklemeyi tamamlamak için Ekle'yi seçin.
- Sayfa Razor Ekle iletişim kutusunu tamamlamak için Ekle'yi seçin.
- Veri bağlamı adını
Aşağıdaki paketler otomatik olarak yüklenir:
Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.VisualStudio.Web.CodeGeneration.Design
Önceki adım başarısız olursa projeyi derleyin ve iskele adımını yeniden deneyin.
yapı iskelesi işlemi:
-
Pages/Students klasöründe Razor sayfalar oluşturur:
-
Create.cshtmlveCreate.cshtml.cs -
Delete.cshtmlveDelete.cshtml.cs -
Details.cshtmlveDetails.cshtml.cs -
Edit.cshtmlveEdit.cshtml.cs -
Index.cshtmlveIndex.cshtml.cs
-
-
Data/SchoolContext.csoluşturur. - Bağlamı,
Program.csiçindeki bağımlılık enjeksiyonuna ekler. -
appsettings.jsonöğesine bir veritabanı bağlantı dizesi ekler.
Veritabanı bağlantı dizesi
Scaffolding aracı, appsettings.json dosyasında bir bağlantı dizesi oluşturur.
bağlantı dizesi SQL Server LocalDB'yi belirtir:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext-0e9;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB, SQL Server Express Veritabanı Altyapısı'nın basit bir sürümüdür ve üretim kullanımına değil uygulama geliştirmeye yöneliktir. Varsayılan olarak, LocalDB C:/Users/<user> dizininde .mdf dosyaları oluşturur.
Veritabanı bağlam sınıfını güncelleştirme
Belirli bir veri modeli için işlevselliği koordine EF Core eden ana sınıf, veritabanı bağlam sınıfıdır. Bağlam, Microsoft.EntityFrameworkCore.DbContext'den elde edilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfın adı SchoolContext'dır.
Aşağıdaki kodla güncelleştirin Data/SchoolContext.cs :
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");
}
}
}
Önceki kod tekil DbSet<Student> Student olandan çoğul DbSet<Student> Studentskoda dönüşür. Sayfalar kodunun Razor yeni DBSet adla eşleşmesini sağlamak için aşağıdakilerden genel bir değişiklik yapın:
_context.Student. ile _context.Students.
8 örnek vardır.
Bir varlık kümesi birden çok varlık içerdiğinden, birçok geliştirici özellik adlarının DBSet çoğul olmasını tercih eder.
Vurgulanan kod:
- Her varlık kümesi için bir DbSet<TEntity> özellik oluşturur. Terminolojide EF Core :
- Varlık kümesi genellikle bir veritabanı tablosuna karşılık gelir.
- Varlık, tablodaki bir satıra karşılık gelir.
-
OnModelCreating çağrısı yapar.
OnModelCreating:-
SchoolContextbaşlatıldıktan sonra, ancak model güvenli hale getirilmeden ve bağlamı başlatmak için kullanılmadan önce çağrılır. - Öğreticinin ilerleyen bölümlerinde
Studentvarlığı diğer varlıklara referanslar içereceği için gereklidir.
-
Bu sorunu gelecek bir sürümde çözmeyi umuyoruz.
Program.cs
ASP.NET Core, bağımlılık ekleme ile oluşturulur. gibi SchoolContext hizmetler, uygulama başlatma sırasında bağımlılık ekleme ile kaydedilir. Sayfalar gibi Razor bu hizmetleri gerektiren bileşenler, oluşturucu parametreleri aracılığıyla bu hizmetlere sağlanır. Veritabanı bağlam örneğini alan oluşturucu kodu öğreticinin ilerleyen bölümlerinde gösterilir.
İskele oluşturma aracı, bağlam sınıfını bağımlılık enjeksiyonu kapsayıcısına otomatik olarak kaydetti.
Aşağıdaki vurgulanan çizgiler iskele tarafından eklendi:
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")));
Bağlantı dizesinin adı, bir DbContextOptions nesnesi üzerinde bir yöntem çağrılarak bağlama aktarılır. Yerel geliştirme için, ASP.NET Core yapılandırma sistemi bağlantı dizesini appsettings.json veya appsettings.Development.json dosyasından okur.
Veritabanı özel durum filtresini ekleme
Aşağıdaki kodda gösterildiği gibi AddDatabaseDeveloperPageExceptionFilter ve UseMigrationsEndPoint ekleyin:
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();
}
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet paketini ekleyin.
NuGet paketini eklemek için Paket Yöneticisi Konsolu'na aşağıdakileri girin:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet paketi, Entity Framework Core hata sayfaları için ASP.NET Core ara yazılımı sağlar. Bu ara yazılım, Entity Framework Core geçişleriyle ilgili hataları algılamaya ve tanılamaya yardımcı olur.
AddDatabaseDeveloperPageExceptionFilter, geliştirme ortamında EF geçiş hataları için yararlı hata bilgileri sağlar.
Veritabanını oluşturma
Mevcut değilse veritabanını oluşturmak için güncelleştirin Program.cs :
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();
Bağlam için bir veritabanı varsa, EnsureCreated yöntemi hiçbir işlem yapmaz. Veritabanı yoksa, veritabanını ve şemayı oluşturur.
EnsureCreated veri modeli değişikliklerini işlemek için aşağıdaki iş akışını etkinleştirir:
- veritabanını silin. Mevcut tüm veriler kaybolur.
- Veri modelini değiştirin. Örneğin, bir
EmailAddressalan ekleyin. - Uygulamayı çalıştırma.
-
EnsureCreatedyeni şemayla bir veritabanı oluşturur.
Verilerin korunması gerekmediği sürece şema hızla geliştikçe bu iş akışı geliştirmenin erken aşamalarında çalışır. Veritabanına girilen verilerin korunması gerektiğinde durum farklıdır. Bu durumda geçişleri kullanın.
Eğitim dizisinin ilerleyen bölümlerinde, EnsureCreated tarafından oluşturulan veritabanı silinir ve geçişler kullanılır. tarafından EnsureCreated oluşturulan bir veritabanı, geçişler kullanılarak güncelleştirilemez.
Uygulamayı test etme
- Uygulamayı çalıştırma.
- Öğrenciler bağlantısını ve ardından Yeni Oluştur'u seçin.
- Düzenle, Ayrıntılar ve Sil bağlantılarını test edin.
Veritabanının tohumunu oluşturma
EnsureCreated yöntemi boş bir veritabanı oluşturur. Bu bölüm, veritabanını test verileriyle dolduran kod ekler.
Aşağıdaki kodla oluşturun Data/DbInitializer.cs :
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();
}
}
}
Kod, veritabanında öğrenci olup olmadığını denetler. Öğrenci yoksa veritabanına test verileri ekler. Performansı iyileştirmek için koleksiyonlar yerine List<T> dizilerde test verilerini oluşturur.
-
Program.csiçinde,DbInitializer.Initializesatırından//öğesini kaldırın:
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
DbInitializer.Initialize(context);
}
Çalışıyorsa uygulamayı durdurun ve Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Drop-Database -Confirmveritabanını silmek için ile
Yyanıt verin.
- Uygulamayı yeniden başlatın.
- Önceden yüklenmiş verileri görmek için Öğrenciler sayfasını seçin.
Veritabanını görüntüleme
- Visual Studio'daki Görünüm menüsünden SQL Server Nesne Gezgini 'yi (SSOX) açın.
- SSOX'ta (localdb)\MSSQLLocalDB > Veritabanları > SchoolContext-{GUID} seçin. Veritabanı adı, daha önce belirtilen bağlam adına bir tire ve bir GUID eklenerek oluşturulur.
- Tablolar düğümünü genişletin.
- Oluşturulan sütunları ve tabloya eklenen satırları görmek için Öğrenci tablosuna sağ tıklayın ve Verileri Görüntüle'ye tıklayın.
-
Student tablosuna sağ tıklayın ve Kodu Görüntüle seçeneğine tıklayarak
StudentmodelininStudenttablo şemasına nasıl eşlendiğini görün.
ASP.NET Core web uygulamalarında zaman uyumsuz EF yöntemleri
Zaman uyumsuz programlama, ASP.NET Core ve EF Coreiçin varsayılan moddur.
Bir web sunucusunun kullanılabilir iş parçacığı sayısı sınırlıdır ve yüksek yük durumlarında tüm kullanılabilir iş parçacıkları kullanımda olabilir. Bu gerçekleştiğinde, iş parçacıkları serbest kalana kadar sunucu yeni istekleri işleyemez. Zaman uyumlu kodla, G/Ç'nin tamamlanmasını bekledikleri için iş yapmadıkları sırada birçok iş parçacığı bağlanabilir. Asenkron kodda, bir işlem G/Ç'nin tamamlanmasını beklerken iş parçacığı serbest bırakılır ve sunucunun diğer istekleri işlemek için onu kullanabilmesi sağlanır. Sonuç olarak, zaman uyumsuz kod sunucu kaynaklarının daha verimli kullanılmasını sağlar ve sunucu gecikme olmadan daha fazla trafiği işleyebilir.
Zaman uyumsuz kod, çalışma zamanında az miktarda ek yük getirir. Düşük trafik durumlarında performans isabeti göz ardı edilebilirken, yüksek trafik durumlarında olası performans artışı önemli düzeydedir.
Aşağıdaki kodda , async anahtar sözcüğü, Task dönüş değeri, await anahtar sözcük ve ToListAsync yöntemi kodun zaman uyumsuz olarak yürütülmesini sağlar.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
-
asyncanahtar sözcüğü derleyiciye aşağıdakileri söyler:- Yöntem gövdesinin bölümleri için geri çağırmalar oluşturun.
- Döndürülen Task nesnesini oluşturun.
-
TaskDönüş türü, devam eden çalışmayı temsil eder. -
awaitanahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, eşzamansız olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma metoduna yerleştirilir. -
ToListAsyncuzantı yönteminin zaman uyumsuz sürümüdürToList.
kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:
- Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler eşzamansız olarak yürütülür.
ToListAsyncBuna , ,SingleOrDefaultAsyncFirstOrDefaultAsyncveSaveChangesAsyncdahildir. Örneğinvar students = context.Students.Where(s => s.LastName == "Davolio")gibi, yalnızca birIQueryable’yi değiştiren ifadeleri içermez. - EF Core bağlamı iş parçacığı güvenli değildir: birden fazla işlemi paralel olarak gerçekleştirmeye çalışmayın.
- Eşzamansız kodun performans avantajlarından yararlanmak için, veritabanına sorgu gönderen EF Core yöntemlerini çağırıyorlarsa kitaplık paketlerinin (örneğin sayfalama için olanların) eşzamansızlığı kullandığını doğrulayın.
.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için Zaman Uyumsuzluğa Genel Bakış ve async ve await ile zaman uyumsuz programlama konularına bakın.
Warning
Microsoft.Data.SqlClient'ın eşzamansız uygulamasının bazı bilinen sorunları vardır (#593, #601 ve diğerleri). Beklenmeyen performans sorunlarıyla karşı karşıyaysanız, özellikle büyük metin veya ikili değerlerle ilgilenirken bunun yerine eşitleme komutu yürütmeyi kullanmayı deneyin.
Performansla ilgili dikkat edilmesi gerekenler
Genel olarak, web sayfası rastgele sayıda satır yüklememelidir. Sorguda sayfalama veya sınırlama yaklaşımı kullanılmalıdır. Örneğin, önceki sorgu döndürülen satırları sınırlamak için kullanabilir Take :
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Bir görünümde büyük bir tablonun listelenmesi sırasında bir veritabanı istisnası oluşursa, kısmen oluşturulmuş bir HTTP 200 yanıtı döndürülebilir.
Sayfalama, eğitimin ilerleyen bölümlerinde ele alınacaktır.
Daha fazla bilgi için bkz . Performansla ilgili dikkat edilmesi gerekenler (EF).
Sonraki Adımlar
Bu, ASP.NET Core Razor Pages uygulamasında Entity Framework (EF) Core'un nasıl kullanılacağını gösteren bir dizi öğreticinin ilkidir. Bu öğretici içerikler, kurgusal Contoso Üniversitesi için bir web sitesi oluşturmanızı sağlar. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Bu öğreticide kod öncelikli yaklaşım kullanılır. Bu öğreticiyi önce veritabanı yaklaşımını kullanarak izlemekle ilgili bilgi için bu Github sorununa bakın.
Tamamlanan uygulamayı indirin veya görüntüleyin.İndirme yönergeleri.
Prerequisites
- Razor Pages kullanmaya yeni başladıysanız, buna başlamadan önce Razor Pages ile çalışmaya başlama eğitim serisini gözden geçirin.
Visual Studio 2022 ile ASP.NET ve web geliştirme iş yükü.
Veritabanı altyapıları
Visual Studio yönergelerinde, SQL Server Express'in yalnızca Windows üzerinde çalışan bir sürümü olan SQL Server LocalDB kullanılır.
Troubleshooting
Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu da StackOverflow.com'da, ASP.NET Core etiketini veya EF Core etiketini kullanarak bir soru sormaktır.
Örnek uygulama
Bu eğitimlerde oluşturulan uygulama, basit bir üniversite web sitesidir. Kullanıcılar öğrenci, kurs ve eğitmen bilgilerini görüntüleyebilir ve güncelleştirebilir. Öğreticide oluşturulan ekranlardan birkaçı aşağıdadır.
Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Bu öğretici, kullanıcı arabirimini nasıl özelleştireceğinize değil, EF Core ASP.NET Core ile nasıl kullanacağınıza odaklanır.
İsteğe bağlı: Örnek indirme paketini oluşturun
Bu adım isteğe bağlıdır. Çözemediğiniz sorunlarla karşılaştığınızda, uygulamanın tamamlanmış sürümünü derlemeniz önerilir. Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. İndirme yönergeleri.
Projeyi açmak için seçin ContosoUniversity.csproj .
- Projeyi derleyin.
- Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Update-Database
Veritabanının tohumunu oluşturmak için projeyi çalıştırın.
Web uygulaması projesi oluşturma
- Visual Studio'yu başlatın ve Yeni proje oluştur'u seçin.
- Yeni proje oluştur iletişim kutusunda ASP.NET Core Web Application> seçin ve İleri'yi seçin.
-
Yeni projenizi yapılandırın iletişim kutusunda, Proje adı için
ContosoUniversitygirin. Büyük/küçük harf kullanımı da dahil olmak üzere tam olarak bu adın kullanılması önemlidir; böylece kod kopyalandığında hernamespaceeşleşir. - Oluştur'i seçin.
-
Yeni ASP.NET Core web uygulaması oluştur iletişim kutusunda şunları seçin:
- .NET Core ve ASP.NET Core 5.0 açılır listelerde.
- ASP.NET Core Web App.
-
Oluştur

Site stilini ayarlama
Aşağıdaki kodu kopyalayıp dosyaya yapıştırın Pages/Shared/_Layout.cshtml :
<!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>
Düzen dosyası site üst bilgisini, alt bilgisini ve menüsünü ayarlar. Yukarıdaki kod aşağıdaki değişiklikleri yapar:
- "ContosoUniversity" ifadesinin geçtiği her yeri "Contoso University" olarak değiştirin. Üç örneği var.
- Home ve Privacy menü girdileri silinir.
- Hakkında, Öğrenciler, Kurslar, Eğitmenler ve Bölümler için girişler eklenir.
içinde Pages/Index.cshtmldosyasının içeriğini aşağıdaki kodla değiştirin:
@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>
Yukarıdaki kod, ASP.NET Core hakkındaki metni bu uygulamayla ilgili metinle değiştirir.
Giriş sayfasının göründüğünü doğrulamak için uygulamayı çalıştırın.
Veri modeli
Aşağıdaki bölümlerde bir veri modeli oluşturulur:
Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.
Student varlığı
Proje klasöründe bir Models klasörü oluşturun.
Aşağıdaki kodla oluşturun
Models/Student.cs: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; } } }
özelliği, ID veritabanı tablosunun bu sınıfa karşılık gelen birincil anahtar sütunu olur. Varsayılan olarak, EF Core veya ID adlı classnameID bir özelliği birincil anahtar olarak yorumlar. Dolayısıyla, Student sınıfının birincil anahtarı için otomatik olarak tanınan alternatif ad StudentID olur. Daha fazla bilgi için bkz EF Core . - Anahtarlar.
Enrollments özelliği bir gezinti özelliğidir. Gezinme özellikleri, bu varlıkla ilişkili diğer varlıkları içerir. Bu durumda, bir Enrollments varlığın Student özelliği o Öğrenci ile ilgili tüm Enrollment varlıkları barındırır. Örneğin, veritabanındaki bir Öğrenci satırında ilişkili iki Kayıt satırı varsa, Enrollments gezinti özelliği bu iki Kayıt varlığını içerir.
Veritabanında, bir Kayıt satırı, StudentID sütunu öğrencinin kimlik numarasını içeriyorsa bir Öğrenci satırıyla ilişkilidir. Örneğin, Bir Öğrenci satırının ID=1 olduğunu varsayalım. İlgili kayıt satırlarında StudentID = 1 olur.
StudentID Kayıt tablosundaki bir yabancı anahtardır .
Birden çok ilişkili Kayıt varlığı olabileceğinden, Enrollments özelliği ICollection<Enrollment> olarak tanımlanır. veya List<Enrollment>gibi HashSet<Enrollment> diğer koleksiyon türleri kullanılabilir. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.
Kaydolma varlığı
Aşağıdaki kodla oluşturun Models/Enrollment.cs :
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; }
}
}
EnrollmentID özelliği birincil anahtardır; bu varlıkta tek başına ID yerine classnameID deseni kullanılır. Bir üretim veri modeli için birçok geliştirici tek bir desen seçer ve bunu tutarlı bir şekilde kullanır. Bu öğreticide her ikisinin de çalıştığını göstermek için her ikisi de kullanılır. olmadan IDclassname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.
Grade özelliği bir enum'dir.
Grade tür bildiriminden sonraki soru işareti, Grade özelliğinin boş değer atanabilir olduğunu gösterir. Null olan bir not sıfırdan farklıdır; null, not bilinmediği veya henüz atanmadığı anlamına gelir.
StudentID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirStudent. Bir Enrollment varlık tek bir Student varlıkla ilişkilendirildiğinden özelliği tek Student bir varlık içerir.
CourseID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirCourse. Bir Enrollment varlık bir Course varlıkla ilişkilendirilir.
EF Core, adı <navigation property name><primary key property name> olan bir özelliği yabancı anahtar olarak yorumlar. Örneğin,StudentID varlığın birincil anahtarı Student olduğundan gezinti özelliğinin Student yabancı anahtarıdır ID. Yabancı anahtar özellikleri ayrıca <primary key property name> olarak adlandırılabilir. Örneğin, Course varlığının birincil anahtarı CourseID olduğundan CourseID.
Kurs varlığı
Aşağıdaki kodla oluşturun Models/Course.cs :
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; }
}
}
Enrollments özelliği bir gezinti özelliğidir. Bir Course varlık, herhangi bir sayıda Enrollment varlıkla ilişkilendirilebilir.
DatabaseGenerated özniteliği, veritabanının bunu oluşturması yerine uygulamanın birincil anahtarı belirtmesine olanak tanır.
Derleyici hatası olmadığını doğrulamak için projeyi derleyin.
Öğrenci sayfalarını yapılandır
Bu bölümde, ASP.NET Core iskele aracı şunları oluşturmak için kullanılır:
- Bir EF Core
DbContextsınıf. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır. Microsoft.EntityFrameworkCore.DbContext sınıfından türetilir. -
Razor varlık için
StudentOluşturma, Okuma, Güncelleştirme ve Silme (CRUD) işlemlerini işleyen sayfalar.
- Sayfalar/Öğrenciler klasörü oluşturun.
- Çözüm Gezgini'nde Pages/Students klasörüne sağ tıklayın ve Ekle>Yeni İskeletlenmiş Öğe'yi seçin.
-
Yeni İskele Öğesi Ekle iletişim kutusunda:
- Sol sekmede Yüklü > Ortak >Razor Sayfaları seçin
- RazorEntity Framework (CRUD) kullanan Sayfalar>ADD seçin.
-
Entity Framework Kullanarak Sayfa Ekleme (CRUD) iletişim kutusunda:
- Model class açılır listesinde Student (ContosoUniversity.Models) seçeneğini belirleyin.
-
Veri bağlamı sınıf satırında (artı) işaretini seçin + .
- Veri bağlamı adını
ContosoUniversityContextyerineSchoolContextile bitecek şekilde değiştirin. Güncelleştirilmiş bağlam adı:ContosoUniversity.Data.SchoolContext - Veri bağlamı sınıfını eklemeyi tamamlamak için Ekle'yi seçin.
- Sayfa Razor Ekle iletişim kutusunu tamamlamak için Ekle'yi seçin.
- Veri bağlamı adını
İskele oluşturma işlemi 'Install the package Microsoft.VisualStudio.Web.CodeGeneration.Design and try again.' hatasıyla başarısız olursa, iskele oluşturma aracını yeniden çalıştırın veya bu GitHub sorununa bakın.
Aşağıdaki paketler otomatik olarak yüklenir:
Microsoft.EntityFrameworkCore.SqlServerMicrosoft.EntityFrameworkCore.ToolsMicrosoft.VisualStudio.Web.CodeGeneration.Design
Önceki adım başarısız olursa projeyi derleyin ve iskele adımını yeniden deneyin.
yapı iskelesi işlemi:
-
Pages/Students klasöründe Razor sayfalar oluşturur:
-
Create.cshtmlveCreate.cshtml.cs -
Delete.cshtmlveDelete.cshtml.cs -
Details.cshtmlveDetails.cshtml.cs -
Edit.cshtmlveEdit.cshtml.cs -
Index.cshtmlveIndex.cshtml.cs
-
-
Data/SchoolContext.csoluşturur. - Bağlamı,
Startup.csiçindeki bağımlılık enjeksiyonuna ekler. -
appsettings.jsonöğesine bir veritabanı bağlantı dizesi ekler.
Veritabanı bağlantı dizesi
Scaffolding aracı, appsettings.json dosyasında bir bağlantı dizesi oluşturur.
bağlantı dizesi SQL Server LocalDB'yi belirtir:
{
"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, SQL Server Express Veritabanı Altyapısı'nın basit bir sürümüdür ve üretim kullanımına değil uygulama geliştirmeye yöneliktir. Varsayılan olarak, LocalDB C:/Users/<user> dizininde .mdf dosyaları oluşturur.
Veritabanı bağlam sınıfını güncelleştirme
Belirli bir veri modeli için işlevselliği koordine EF Core eden ana sınıf, veritabanı bağlam sınıfıdır. Bağlam, Microsoft.EntityFrameworkCore.DbContext'den elde edilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfın adı SchoolContext'dır.
Aşağıdaki kodla güncelleştirin Data/SchoolContext.cs :
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");
}
}
}
Önceki kod tekil DbSet<Student> Student olandan çoğul DbSet<Student> Studentskoda dönüşür. Sayfalar kodunun Razor yeni DBSet adla eşleşmesini sağlamak için aşağıdakilerden genel bir değişiklik yapın:
_context.Student. ile _context.Students.
8 örnek vardır.
Bir varlık kümesi birden çok varlık içerdiğinden, birçok geliştirici özellik adlarının DBSet çoğul olmasını tercih eder.
Vurgulanan kod:
- Her varlık kümesi için bir DbSet<TEntity> özellik oluşturur. Terminolojide EF Core :
- Varlık kümesi genellikle bir veritabanı tablosuna karşılık gelir.
- Varlık, tablodaki bir satıra karşılık gelir.
-
OnModelCreating çağrısı yapar.
OnModelCreating:-
SchoolContextbaşlatıldıktan sonra, ancak model güvenli hale getirilmeden ve bağlamı başlatmak için kullanılmadan önce çağrılır. - Öğreticinin ilerleyen bölümlerinde
Studentvarlığı diğer varlıklara referanslar içereceği için gereklidir.
-
Derleyici hatası olmadığını doğrulamak için projeyi derleyin.
Startup.cs
ASP.NET Core, bağımlılık ekleme ile oluşturulur. gibi SchoolContext hizmetler, uygulama başlatma sırasında bağımlılık ekleme ile kaydedilir. Sayfalar gibi Razor bu hizmetleri gerektiren bileşenler, oluşturucu parametreleri aracılığıyla bu hizmetlere sağlanır. Veritabanı bağlam örneğini alan oluşturucu kodu öğreticinin ilerleyen bölümlerinde gösterilir.
İskele oluşturma aracı, bağlam sınıfını bağımlılık enjeksiyonu kapsayıcısına otomatik olarak kaydetti.
Aşağıdaki vurgulanan çizgiler iskele tarafından eklendi:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddDbContext<SchoolContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
}
Bağlantı dizesinin adı, bir DbContextOptions nesnesi üzerinde bir yöntem çağrılarak bağlama aktarılır. Yerel geliştirme için ASP.NET Core yapılandırma sistemi dosyadan appsettings.json bağlantı dizesi okur.
Veritabanı özel durum filtresini ekleme
Aşağıdaki kodda gösterildiği gibi AddDatabaseDeveloperPageExceptionFilter ve UseMigrationsEndPoint ekleyin:
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();
});
}
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet paketini ekleyin.
NuGet paketini eklemek için Paket Yöneticisi Konsolu'na aşağıdakileri girin:
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet paketi, Entity Framework Core hata sayfaları için ASP.NET Core ara yazılımı sağlar. Bu ara yazılım, Entity Framework Core geçişleriyle ilgili hataları algılamaya ve tanılamaya yardımcı olur.
AddDatabaseDeveloperPageExceptionFilter, geliştirme ortamında EF geçiş hataları için yararlı hata bilgileri sağlar.
Veritabanını oluşturma
Mevcut değilse veritabanını oluşturmak için güncelleştirin Program.cs :
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>();
});
}
}
Bağlam için bir veritabanı varsa, EnsureCreated yöntemi hiçbir işlem yapmaz. Veritabanı yoksa, veritabanını ve şemayı oluşturur.
EnsureCreated veri modeli değişikliklerini işlemek için aşağıdaki iş akışını etkinleştirir:
- veritabanını silin. Mevcut tüm veriler kaybolur.
- Veri modelini değiştirin. Örneğin, bir
EmailAddressalan ekleyin. - Uygulamayı çalıştırma.
-
EnsureCreatedyeni şemayla bir veritabanı oluşturur.
Verilerin korunması gerekmediği sürece şema hızla geliştikçe bu iş akışı geliştirmenin erken aşamalarında çalışır. Veritabanına girilen verilerin korunması gerektiğinde durum farklıdır. Bu durumda geçişleri kullanın.
Eğitim dizisinin ilerleyen bölümlerinde, EnsureCreated tarafından oluşturulan veritabanı silinir ve geçişler kullanılır. tarafından EnsureCreated oluşturulan bir veritabanı, geçişler kullanılarak güncelleştirilemez.
Uygulamayı test etme
- Uygulamayı çalıştırma.
- Öğrenciler bağlantısını ve ardından Yeni Oluştur'u seçin.
- Düzenle, Ayrıntılar ve Sil bağlantılarını test edin.
Veritabanının tohumunu oluşturma
EnsureCreated yöntemi boş bir veritabanı oluşturur. Bu bölüm, veritabanını test verileriyle dolduran kod ekler.
Aşağıdaki kodla oluşturun Data/DbInitializer.cs :
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();
}
}
}
Kod, veritabanında öğrenci olup olmadığını denetler. Öğrenci yoksa veritabanına test verileri ekler. Performansı iyileştirmek için koleksiyonlar yerine List<T> dizilerde test verilerini oluşturur.
Program.csiçinde,DbInitializer.Initializesatırından//öğesini kaldırın:context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Çalışıyorsa uygulamayı durdurun ve Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Drop-Database -Confirmveritabanını silmek için ile
Yyanıt verin.
- Uygulamayı yeniden başlatın.
- Önceden yüklenmiş verileri görmek için Öğrenciler sayfasını seçin.
Veritabanını görüntüleme
- Visual Studio'daki Görünüm menüsünden SQL Server Nesne Gezgini 'yi (SSOX) açın.
- SSOX'ta (localdb)\MSSQLLocalDB > Veritabanları > SchoolContext-{GUID} seçin. Veritabanı adı, daha önce belirtilen bağlam adına bir tire ve bir GUID eklenerek oluşturulur.
- Tablolar düğümünü genişletin.
- Oluşturulan sütunları ve tabloya eklenen satırları görmek için Öğrenci tablosuna sağ tıklayın ve Verileri Görüntüle'ye tıklayın.
-
Student tablosuna sağ tıklayın ve Kodu Görüntüle seçeneğine tıklayarak
StudentmodelinStudenttablo şemasına nasıl eşlendiğini görün.
Zaman uyumsuz kod
Zaman uyumsuz programlama, ASP.NET Core ve EF Coreiçin varsayılan moddur.
Bir web sunucusunun kullanılabilir iş parçacığı sayısı sınırlıdır ve yüksek yük durumlarında tüm kullanılabilir iş parçacıkları kullanımda olabilir. Bu olduğunda, iş parçacıkları serbest kalana kadar sunucu yeni istekleri işleyemez. Zaman uyumlu kodla, G/Ç'nin tamamlanmasını bekledikleri için iş yapmadıkları sırada birçok iş parçacığı bağlanabilir. Eşzamansız kodda, bir işlem G/Ç’nin tamamlanmasını beklerken ilgili iş parçacığı, sunucunun diğer istekleri işlemek için kullanabileceği şekilde boşa çıkar. Sonuç olarak, zaman uyumsuz kod sunucu kaynaklarının daha verimli kullanılmasını sağlar ve sunucu gecikme olmadan daha fazla trafiği işleyebilir.
Zaman uyumsuz kod, çalışma zamanında az miktarda ek yük getirir. Düşük trafik durumlarında performans isabeti göz ardı edilebilirken, yüksek trafik durumlarında olası performans artışı önemli düzeydedir.
Aşağıdaki kodda , async anahtar sözcüğü, Task dönüş değeri, await anahtar sözcük ve ToListAsync yöntemi kodun zaman uyumsuz olarak yürütülmesini sağlar.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
-
asyncanahtar sözcüğü derleyiciye aşağıdakileri söyler:- Yöntem gövdesinin bölümleri için geri çağırmalar oluşturun.
- Döndürülen Task nesnesini oluşturun.
-
TaskDönüş türü, devam eden çalışmayı temsil eder. -
awaitanahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, eşzamansız olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma metoduna yerleştirilir. -
ToListAsyncuzantı yönteminin zaman uyumsuz sürümüdürToList.
kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:
- Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler eşzamansız olarak yürütülür.
ToListAsyncBuna , ,SingleOrDefaultAsyncFirstOrDefaultAsyncveSaveChangesAsyncdahildir. Yalnızca birIQueryableöğesini değiştiren ifadeleri içermez; örneğinvar students = context.Students.Where(s => s.LastName == "Davolio"). - Bir EF Core bağlam iş parçacığı güvenli değildir: birden çok işlemi paralel olarak yapmaya çalışmayın.
- Asenkron kodun performans avantajlarından yararlanmak için, kitaplık paketlerinin (örneğin sayfalama için olanların), veritabanına sorgu gönderen EF Core yöntemlerini çağırıyorlarsa asenkron kullandığını doğrulayın.
.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için Zaman Uyumsuzluğa Genel Bakış ve async ve await ile zaman uyumsuz programlama konularına bakın.
Performansla ilgili dikkat edilmesi gerekenler
Genel olarak, web sayfası rastgele sayıda satır yüklememelidir. Sorguda sayfalama veya sınırlama yaklaşımı kullanılmalıdır. Örneğin, önceki sorgu döndürülen satırları sınırlamak için kullanabilir Take :
public async Task OnGetAsync()
{
Student = await _context.Students.Take(10).ToListAsync();
}
Bir görünümde büyük bir tablonun listelenmesi sırasında bir veritabanı istisnası oluşursa, kısmen oluşturulmuş bir HTTP 200 yanıtı döndürülebilir.
MaxModelBindingCollectionSize varsayılan değeri 1024'tir. Aşağıdaki kod, MaxModelBindingCollectionSize değerini ayarlar:
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();
}
MyMaxModelBindingCollectionSize gibi yapılandırma ayarları hakkında bilgi için Yapılandırma bölümüne bakın.
Sayfalama, eğitimin ilerleyen bölümlerinde ele alınacaktır.
Daha fazla bilgi için bkz . Performansla ilgili dikkat edilmesi gerekenler (EF).
Entity Framework Core'un SQL Günlüğü
Günlüğe kaydetme yapılandırması genellikle appsettings.{Environment}.json dosyalarının Logging bölümünde sağlanır. SQL ifadelerini günlüğe kaydetmek için "Microsoft.EntityFrameworkCore.Database.Command": "Information" öğesini appsettings.Development.json dosyasına ekleyin:
{
"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": "*"
}
Yukarıdaki JSON ile, SQL deyimleri komut satırında ve Visual Studio çıkış penceresinde görüntülenir.
Daha fazla bilgi için aşağıdaki kaynaklara bakın:
- .NET ve ASP.NET Core'da oturum açma
-
ASP.NET şablonu SQL günlüğünü varsayılan olarak devre dışı bırakır EF Core (
dotnet/aspnetcore#32977)
Sonraki Adımlar
Bu, ASP.NET Core Razor Pages uygulamasında Entity Framework (EF) Core'un nasıl kullanılacağını gösteren bir dizi öğreticinin ilkidir. Bu öğretici içerikler, kurgusal Contoso Üniversitesi için bir web sitesi oluşturmanızı sağlar. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Bu öğreticide kod öncelikli yaklaşım kullanılır. Bu öğreticiyi önce veritabanı yaklaşımını kullanarak izlemekle ilgili bilgi için bu Github sorununa bakın.
Tamamlanan uygulamayı indirin veya görüntüleyin.İndirme yönergeleri.
Prerequisites
- Razor Pages kullanmaya yeni başladıysanız, buna başlamadan önce Razor Pages ile çalışmaya başlama eğitim serisini gözden geçirin.
Visual Studio 2022 ile ASP.NET ve web geliştirme iş yükü.
Veritabanı altyapıları
Visual Studio yönergelerinde, SQL Server Express'in yalnızca Windows üzerinde çalışan bir sürümü olan SQL Server LocalDB kullanılır.
Visual Studio Code yönergelerinde platformlar arası bir veritabanı altyapısı olan SQLite kullanılır.
SQLite kullanmayı seçerseniz, SQLite için DB Tarayıcısı gibi bir SQLite veritabanını yönetmek ve görüntülemek için bir üçüncü taraf aracı indirip yükleyin.
Troubleshooting
Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu da StackOverflow.com'da, ASP.NET Core etiketini veya EF Core etiketini kullanarak bir soru sormaktır.
Örnek uygulama
Bu eğitimlerde oluşturulan uygulama, basit bir üniversite web sitesidir. Kullanıcılar öğrenci, kurs ve eğitmen bilgilerini görüntüleyebilir ve güncelleştirebilir. Öğreticide oluşturulan ekranlardan birkaçı aşağıdadır.
Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Öğreticinin odak noktası, kullanıcı arabirimini nasıl özelleştireceğiniz değil, EF Core nasıl kullanacağınızdır.
Tamamlanan projenin kaynak kodunu almak için sayfanın üst kısmındaki bağlantıyı izleyin. cu30 klasöründe öğreticinin ASP.NET Core 3.0 sürümünün kodu bulunur. Öğreticiler 1-7 için kodun durumunu yansıtan dosyalar cu30snapshots klasöründe bulunabilir.
Tamamlanmış projeyi indirdikten sonra uygulamayı çalıştırmak için:
Projeyi derleyin.
Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Update-DatabaseVeritabanının tohumunu oluşturmak için projeyi çalıştırın.
Web uygulaması projesi oluşturma
- Visual Studio Dosya menüsünden Yeni>Proje seçeneğini seçin.
- ASP.NET Çekirdek Web Uygulaması'nı seçin.
- Projeyi ContosoUniversity olarak adlandırın. Kod kopyalanıp yapıştırıldığında ad alanlarının eşleşmesi için büyük harf kullanımı da dahil olmak üzere tam olarak bu adın kullanılması önemlidir.
- Açılan listeden .NET Core ve ASP.NET Core 3.0'ı ve ardından Web Uygulaması'nı seçin.
Site stilini ayarlama
Pages/Shared/_Layout.cshtml öğesini güncelleyerek site başlığını, alt bilgisini ve menüsünü ayarlayın:
"ContosoUniversity" ifadesinin her örneğini "Contoso University" olarak değiştirin. Üç örneği var.
Home ve Privacy menü girdilerini silin ve Hakkında, Öğrenciler, Kurslar, Eğitmenler ve Bölümler için girdiler ekleyin.
Değişiklikler vurgulanır.
<!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>
içinde Pages/Index.cshtmldosyasının içeriğini aşağıdaki kodla değiştirerek ASP.NET Core hakkındaki metni bu uygulamayla ilgili metinle değiştirin:
@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>
Giriş sayfasının göründüğünü doğrulamak için uygulamayı çalıştırın.
Veri modeli
Aşağıdaki bölümlerde bir veri modeli oluşturulur:
Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.
Student varlığı
Proje klasöründe bir Models klasörü oluşturun.
Aşağıdaki kodla oluşturun
Models/Student.cs: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; } } }
özelliği, ID veritabanı tablosunun bu sınıfa karşılık gelen birincil anahtar sütunu olur. Varsayılan olarak, EF Core veya ID adlı classnameID bir özelliği birincil anahtar olarak yorumlar. Dolayısıyla, Student sınıfının birincil anahtarı için otomatik olarak tanınan alternatif ad StudentID olur. Daha fazla bilgi için bkz EF Core . - Anahtarlar.
Enrollments özelliği bir gezinti özelliğidir. Gezinme özellikleri, bu varlıkla ilişkili diğer varlıkları içerir. Bu durumda, bir Enrollments varlığın Student özelliği o Öğrenci ile ilgili tüm Enrollment varlıkları barındırır. Örneğin, veritabanındaki bir Öğrenci satırında ilişkili iki Kayıt satırı varsa, Enrollments gezinti özelliği bu iki Kayıt varlığını içerir.
Veritabanında, StudentID sütunu öğrencinin kimlik değerini içeriyorsa, Kayıt satırı Öğrenci satırıyla ilişkilidir. Örneğin, Bir Öğrenci satırının ID=1 olduğunu varsayalım. İlgili Kayıt satırlarının StudentID = 1 olacaktır. StudentID, Kayıt tablosundaki bir yabancı anahtardır .
Birden çok ilişkili Kayıt varlığı olabileceğinden, Enrollments özelliği ICollection<Enrollment> olarak tanımlanır. veya List<Enrollment>gibi HashSet<Enrollment> diğer koleksiyon türlerini kullanabilirsiniz. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.
Kaydolma varlığı
Aşağıdaki kodla oluşturun Models/Enrollment.cs :
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; }
}
}
EnrollmentID özelliği birincil anahtardır; bu varlıkta tek başına ID yerine classnameID deseni kullanılır. Üretim veri modeli için bir desen seçin ve bunu tutarlı bir şekilde kullanın. Bu öğreticide her ikisinin de çalıştığını göstermek için her ikisi de kullanılır. olmadan IDclassname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.
Grade özelliği bir enum'dir.
Grade tür bildiriminden sonraki soru işareti, Grade özelliğinin boş değer atanabilir olduğunu gösterir. Null olan bir not sıfırdan farklıdır; null, not bilinmediği veya henüz atanmadığı anlamına gelir.
StudentID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirStudent. Bir Enrollment varlık tek bir Student varlıkla ilişkilendirildiğinden özelliği tek Student bir varlık içerir.
CourseID özelliği bir yabancı anahtardır ve buna karşılık gelen gezinti özelliği şeklindedirCourse. Bir Enrollment varlık bir Course varlıkla ilişkilendirilir.
EF Core, adı <navigation property name><primary key property name> olan bir özelliği yabancı anahtar olarak yorumlar. Örneğin,StudentID varlığın birincil anahtarı Student olduğundan gezinti özelliğinin Student yabancı anahtarıdır ID. Yabancı anahtar özellikleri ayrıca <primary key property name> olarak adlandırılabilir. Örneğin, Course varlığının birincil anahtarı CourseID olduğundan CourseID.
Kurs varlığı
Aşağıdaki kodla oluşturun Models/Course.cs :
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; }
}
}
Enrollments özelliği bir gezinti özelliğidir. Bir Course varlık, herhangi bir sayıda Enrollment varlıkla ilişkilendirilebilir.
DatabaseGenerated özniteliği, veritabanının bunu oluşturması yerine uygulamanın birincil anahtarı belirtmesine olanak tanır.
Derleyici hatası olmadığını doğrulamak için projeyi derleyin.
Öğrenci sayfalarını yapılandır
Bu bölümde, aşağıdakileri oluşturmak için ASP.NET Core iskelet oluşturma aracını kullanacaksınız:
- Bir EF Corebağlam sınıfı. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır.
Microsoft.EntityFrameworkCore.DbContextsınıfından türetilir. -
Razor varlık için
StudentOluşturma, Okuma, Güncelleştirme ve Silme (CRUD) işlemlerini işleyen sayfalar.
- Sayfalar klasöründe bir Öğrenciler klasörü oluşturun.
- Çözüm Gezgini'nde Pages/Students klasörüne sağ tıklayın ve Ekle>Yeni İskeletlenmiş Öğe'yi seçin.
- İskele Ekle iletişim kutusunda, RazorEntity Framework kullanan Sayfalar (CRUD)>EKLE seçeneğini belirleyin.
-
Entity Framework Kullanarak Sayfa Ekleme (CRUD) iletişim kutusunda:
- Model class açılır listesinde Student (ContosoUniversity.Models) seçeneğini belirleyin.
- Veri bağlamı sınıf satırında (artı) işaretini seçin + .
- ContosoUniversity.Models.ContosoUniversityContextolan veri bağlamı adını ContosoUniversity.Data.SchoolContext olarak değiştirin.
- Add (Ekle) seçeneğini belirleyin.
Aşağıdaki paketler otomatik olarak yüklenir:
Microsoft.VisualStudio.Web.CodeGeneration.DesignMicrosoft.EntityFrameworkCore.SqlServerMicrosoft.Extensions.Logging.DebugMicrosoft.EntityFrameworkCore.Tools
Önceki adımla ilgili bir sorun yaşıyorsanız projeyi derleyin ve iskele adımını yeniden deneyin.
yapı iskelesi işlemi:
-
Pages/Students klasöründe Razor sayfalar oluşturur:
-
Create.cshtmlveCreate.cshtml.cs -
Delete.cshtmlveDelete.cshtml.cs -
Details.cshtmlveDetails.cshtml.cs -
Edit.cshtmlveEdit.cshtml.cs -
Index.cshtmlveIndex.cshtml.cs
-
-
Data/SchoolContext.csoluşturur. - Bağlamı,
Startup.csiçindeki bağımlılık enjeksiyonuna ekler. -
appsettings.jsonöğesine bir veritabanı bağlantı dizesi ekler.
Veritabanı bağlantı dizesi
Dosya, appsettings.json SQL Server LocalDB bağlantı dizesi belirtir.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext6;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
LocalDB, SQL Server Express Veritabanı Altyapısı'nın basit bir sürümüdür ve üretim kullanımına değil uygulama geliştirmeye yöneliktir. Varsayılan olarak, LocalDB C:/Users/<user> dizininde .mdf dosyaları oluşturur.
Veritabanı bağlam sınıfını güncelleştirme
Belirli bir veri modeli için işlevselliği koordine EF Core eden ana sınıf, veritabanı bağlam sınıfıdır. Bağlam, Microsoft.EntityFrameworkCore.DbContext'den elde edilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfın adı SchoolContext'dır.
Aşağıdaki kodla güncelleştirin Data/SchoolContext.cs :
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");
}
}
}
Vurgulanan kod, her varlık kümesi için bir DbSet<TEntity> özellik oluşturur. Terminolojide EF Core :
- Varlık kümesi genellikle bir veritabanı tablosuna karşılık gelir.
- Varlık, tablodaki bir satıra karşılık gelir.
Bir varlık kümesi birden çok varlık içerdiğinden DBSet özellikleri çoğul adlar olmalıdır. İskele oluşturma aracı bir Student DBSet oluşturduğundan, bu adım bunu çoğul hali olan Students olarak değiştirir.
Sayfalar kodunun Razor yeni DBSet adıyla eşleşmesini sağlamak için, tüm projesinde _context.Student_context.Studentsile genel bir değişiklik yapın. 8 örnek vardır.
Derleyici hatası olmadığını doğrulamak için projeyi derleyin.
Startup.cs
ASP.NET Core, bağımlılık ekleme ile oluşturulur. Hizmetler (veritabanı bağlamı EF Core gibi) uygulama başlatma sırasında bağımlılık ekleme ile kaydedilir. Bu hizmetleri gerektiren bileşenler (Sayfalar gibi Razor ) oluşturucu parametreleri aracılığıyla bu hizmetler sağlanır. Veritabanı bağlam örneğini alan oluşturucu kodu öğreticinin ilerleyen bölümlerinde gösterilir.
İskele oluşturma aracı, bağlam sınıfını bağımlılık enjeksiyonu kapsayıcısına otomatik olarak kaydetti.
içinde
ConfigureServices, vurgulanan çizgiler iskele tarafından eklendi:public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddDbContext<SchoolContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SchoolContext"))); }
Bağlantı dizesinin adı, bir DbContextOptions nesnesi üzerinde bir yöntem çağrılarak bağlama aktarılır. Yerel geliştirme için ASP.NET Core yapılandırma sistemi dosyadan appsettings.json bağlantı dizesi okur.
Veritabanını oluşturma
Mevcut değilse veritabanını oluşturmak için güncelleştirin Program.cs :
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>();
});
}
}
Bağlam için bir veritabanı varsa, EnsureCreated yöntemi hiçbir işlem yapmaz. Veritabanı yoksa, veritabanını ve şemayı oluşturur.
EnsureCreated veri modeli değişikliklerini işlemek için aşağıdaki iş akışını etkinleştirir:
- veritabanını silin. Mevcut tüm veriler kaybolur.
- Veri modelini değiştirin. Örneğin, bir
EmailAddressalan ekleyin. - Uygulamayı çalıştırma.
-
EnsureCreatedyeni şemayla bir veritabanı oluşturur.
Bu iş akışı, verileri korumanız gerekmediği sürece şema hızla geliştikçe geliştirme aşamasında iyi çalışır. Veritabanına girilen verilerin korunması gerektiğinde durum farklıdır. Bu durumda geçişleri kullanın.
Öğretici dizisinin ilerleyen bölümlerinde, EnsureCreated tarafından oluşturulan veritabanını siler ve bunun yerine migration'ları kullanırsınız. tarafından EnsureCreated oluşturulan bir veritabanı, geçişler kullanılarak güncelleştirilemez.
Uygulamayı test etme
- Uygulamayı çalıştırma.
- Öğrenciler bağlantısını ve ardından Yeni Oluştur'u seçin.
- Düzenle, Ayrıntılar ve Sil bağlantılarını test edin.
Veritabanının tohumunu oluşturma
EnsureCreated yöntemi boş bir veritabanı oluşturur. Bu bölüm, veritabanını test verileriyle dolduran kod ekler.
Aşağıdaki kodla oluşturun Data/DbInitializer.cs :
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();
}
}
}
Kod, veritabanında öğrenci olup olmadığını denetler. Öğrenci yoksa veritabanına test verileri ekler. Performansı iyileştirmek için koleksiyonlar yerine List<T> dizilerde test verilerini oluşturur.
Program.csiçinde,EnsureCreatedçağrısınıDbInitializer.Initializeçağrısıyla değiştirin:// context.Database.EnsureCreated(); DbInitializer.Initialize(context);
Çalışıyorsa uygulamayı durdurun ve Paket Yöneticisi Konsolu'nda (PMC) aşağıdaki komutu çalıştırın:
Drop-Database
Uygulamayı yeniden başlatın.
Önceden yüklenmiş verileri görmek için Öğrenciler sayfasını seçin.
Veritabanını görüntüleme
- Visual Studio'daki Görünüm menüsünden SQL Server Nesne Gezgini 'yi (SSOX) açın.
- SSOX'ta (localdb)\MSSQLLocalDB > Veritabanları > SchoolContext-{GUID} seçin. Veritabanı adı, daha önce belirttiğiniz bağlam adından, bir tire işareti ile bir GUID’nin birleşiminden oluşturulur.
- Tablolar düğümünü genişletin.
- Oluşturulan sütunları ve tabloya eklenen satırları görmek için Öğrenci tablosuna sağ tıklayın ve Verileri Görüntüle'ye tıklayın.
-
Student tablosuna sağ tıklayın ve Kodu Görüntüle seçeneğine tıklayarak
StudentmodelinStudenttablo şemasına nasıl eşlendiğini görün.
Zaman uyumsuz kod
Zaman uyumsuz programlama, ASP.NET Core ve EF Coreiçin varsayılan moddur.
Bir web sunucusunun kullanılabilir iş parçacığı sayısı sınırlıdır ve yüksek yük durumlarında tüm kullanılabilir iş parçacıkları kullanımda olabilir. Bu olduğunda, iş parçacıkları serbest kalana kadar sunucu yeni istekleri işleyemez. Eşzamanlı kodda, birçok iş parçacığı gerçekte herhangi bir iş yapmıyor olsalar da G/Ç işlemlerinin tamamlanmasını bekledikleri için meşgul kalabilir. Eşzamansız kodda, bir işlem G/Ç’nin tamamlanmasını beklerken ilgili iş parçacığı, sunucunun diğer istekleri işlemek için kullanabileceği şekilde boşa çıkar. Sonuç olarak, zaman uyumsuz kod sunucu kaynaklarının daha verimli kullanılmasını sağlar ve sunucu gecikme olmadan daha fazla trafiği işleyebilir.
Zaman uyumsuz kod, çalışma zamanında az miktarda ek yük getirir. Düşük trafik durumlarında performans isabeti göz ardı edilebilirken, yüksek trafik durumlarında olası performans artışı önemli düzeydedir.
Aşağıdaki kodda , async anahtar sözcüğü, Task<T> dönüş değeri, await anahtar sözcük ve ToListAsync yöntemi kodun zaman uyumsuz olarak yürütülmesini sağlar.
public async Task OnGetAsync()
{
Students = await _context.Students.ToListAsync();
}
-
asyncanahtar sözcüğü derleyiciye aşağıdakileri söyler:- Yöntem gövdesinin bölümleri için geri çağırmalar oluşturun.
- Döndürülen Task nesnesini oluşturun.
-
Task<T>Dönüş türü, devam eden çalışmayı temsil eder. -
awaitanahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, eşzamansız olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma metoduna yerleştirilir. -
ToListAsyncuzantı yönteminin zaman uyumsuz sürümüdürToList.
kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:
- Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler eşzamansız olarak yürütülür.
ToListAsyncBuna , ,SingleOrDefaultAsyncFirstOrDefaultAsyncveSaveChangesAsyncdahildir. Yalnızca birIQueryableöğesini değiştiren ifadeleri içermez; örneğinvar students = context.Students.Where(s => s.LastName == "Davolio"). - Bir EF Core bağlam iş parçacığı güvenli değildir: birden çok işlemi paralel olarak yapmaya çalışmayın.
- Asenkron kodun performans avantajlarından yararlanmak için, kitaplık paketlerinin (örneğin sayfalama için olanların), veritabanına sorgu gönderen EF Core yöntemlerini çağırıyorlarsa asenkron kullandığını doğrulayın.
.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için Zaman Uyumsuzluğa Genel Bakış ve async ve await ile zaman uyumsuz programlama konularına bakın.
Sonraki Adımlar
ASP.NET Core