Razor ASP.NET Core'da Entity Framework Core içeren sayfalar - Öğretici 1 / 8

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Uyarı

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 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 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. Öğreticiler, kurgusal bir Contoso Üniversitesi için bir web sitesi oluşturur. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Öğreticide ilk olarak kod yaklaşımı kullanılır. Veritabanı ilk yaklaşımını kullanarak bu öğreticiyi izleme hakkında bilgi için bu Github sorununa bakın.

Tamamlanan uygulamayı indirin veya görüntüleyin. İndirme yönergeleri.

Önkoşullar

  • Sayfalar'ı kullanmaya yeni başladıysanız, bu sayfayı Razor başlatmadan önce Sayfaları kullanmaya Razor başlama öğretici serisini inceleyin.

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.

Sorun giderme

Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu, ASP.NET Core etiketini veya etiketini kullanarak StackOverflow.com bir soru göndermektirEF Core.

Örnek uygulama

Bu öğreticilerde oluşturulan uygulama, temel 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.

Öğrenci Dizini sayfası

Öğrenciler Düzenleme sayfası

Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Öğreticinin odak noktası, kullanıcı arabiriminin nasıl özelleştirileceği değil ASP.NET Core ile nasıl kullanılacağıdır EF Core .

İsteğe bağlı: Örnek indirmeyi derleme

Bu adım isteğe bağlıdır. Çözemezseniz tamamlanmış uygulamayı 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

  1. Visual Studio 2022'yi başlatın ve Yeni proje oluştur'u seçin.

    Başlangıç penceresinden yeni proje oluşturma

  2. Yeni proje oluştur iletişim kutusunda ASP.NET Core Web App'i ve ardından İleri'yi seçin.

    ASP.NET Core Web Uygulaması oluşturma

  3. Yeni projenizi yapılandırın iletişim kutusunda Proje adı için girinContosoUniversity. 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.

  4. İleri'yi seçin.

  5. Ek bilgi iletişim kutusunda .NET 6.0 (uzun süreli destek) öğesini ve ardından Oluştur'u seçin.

    Ek bilgi

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">
            &copy; 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" öğesinin "Contoso University" olarak her oluşumu. Üç oluşum vardır.
  • 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.

Sayfanın göründüğünü doğrulamak home için uygulamayı çalıştırın.

Veri modeli

Aşağıdaki bölümlerde bir veri modeli oluşturulur:

Kurs-Kayıt-Öğrenci veri modeli diyagramı

Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.

Student varlığı

Öğrenci varlık diyagramı

  • 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 classnameID adlı ID bir özelliği birincil anahtar olarak yorumlar. Bu nedenle, sınıf birincil anahtarı için Student alternatif olarak tanınan ad olur StudentID. Daha fazla bilgi için bkz EF Core . - Anahtarlar.

Enrollments özelliği bir gezinti özelliğidir. Gezinti özellikleri, bu varlıkla ilgili diğer varlıkları barındırır. Bu durumda, bir Student varlığın Enrollments ö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ı, sütunu öğrencinin kimlik değerini içeriyorsa Öğrenci satırıyla StudentID ilişkilidir. Örneğin, Bir Öğrenci satırının ID=1 olduğunu varsayalım. İlgili Kayıt satırları = 1 olacaktır StudentID . StudentID Kayıt tablosundaki bir yabancı anahtardır .

Enrollments özelliği, birden çok ilişkili Kayıt varlığı olabileceğinden olarak ICollection<Enrollment> tanımlanır. veya HashSet<Enrollment>gibi List<Enrollment> diğer koleksiyon türleri kullanılabilir. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.

Kayıt varlığı

Kayıt varlığı diyagramı

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ık kendi başına değil ID desenini classnameID kullanı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 ID classname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.

Grade özelliği bir enum'dir. Tür bildiriminden Grade sonraki soru işareti özelliğin Grade null 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 adlı <navigation property name><primary key property name>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 olarak da adlandırılabilir <primary key property name>. Örneğin, CourseID varlığın Course birincil anahtarı olduğundan CourseID.

Kurs varlığı

Kurs varlığı diyagramı

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.

özniteliği, DatabaseGenerated veritabanının oluşturmasını sağlamak 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 Öğreticiye bakın: Tasarım amacınızı null atanabilir ve null atanamaz başvuru türleriyle daha net ifade edin.

Boş değer atanabilir başvuru türlerindeki uyarıları ortadan kaldırmak için dosyadan ContosoUniversity.csproj aşağıdaki satırı kaldırın:

<Nullable>enable</Nullable>

yapı iskelesi altyapısı şu anda null atanabilir başvuru türlerini desteklemediğinden, iskelede kullanılan modeller de destekleyemez.

? projenin derleyici uyarıları olmadan derlenebilmesi için içindeki Pages/Error.cshtml.cs null atanabilir başvuru türü ek açıklamasını public string? RequestId { get; set; } kaldırın.

yapı iskelesi Öğrenci sayfaları

Bu bölümde, ASP.NET Core iskele aracı şunları oluşturmak için kullanılır:

  • Bir EF CoreDbContext sınıf. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır. sınıfından Microsoft.EntityFrameworkCore.DbContext türetilir.
  • Razor varlık için Student Oluşturma, Okuma, Güncelleştirme ve Silme (CRUD) işlemlerini işleyen sayfalar.
  • Sayfalar/Öğrenciler klasörü oluşturun.
  • Çözüm Gezgini Sayfalar/Öğrenciler klasörüne sağ tıklayın ve Yeni İskeleli Öğe Ekle'yi>seçin.
  • Yeni İskele Öğesi Ekle iletişim kutusunda:
    • Sol sekmede Yüklü OrtakRazor >Sayfalar'ı seçin >
    • Entity Framework (CRUD)ADD kullanan sayfalar'ı> seçin.Razor
  • Entity Framework (CRUD) kullanarak Sayfa Ekle Razor iletişim kutusunda:
    • Model sınıfı açılan listesinde Öğrenci (ContosoUniversity.Models) öğesini seçin.
    • Veri bağlamı sınıf satırında (artı) işaretini seçin + .
      • Veri bağlamı adını yerine ContosoUniversityContextile bitecek şekilde SchoolContext 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.
      • Ekle'yi seçerek Sayfa Ekle Razor iletişim kutusunu tamamlayın.

Aşağıdaki paketler otomatik olarak yüklenir:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.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:

  • Sayfalar/Öğrenciler klasöründe sayfalar oluştururRazor:
    • Create.cshtml ve Create.cshtml.cs
    • Delete.cshtml ve Delete.cshtml.cs
    • Details.cshtml ve Details.cshtml.cs
    • Edit.cshtml ve Edit.cshtml.cs
    • Index.cshtml ve Index.cshtml.cs
  • oluşturur Data/SchoolContext.cs.
  • bağlamını içindeki Program.csbağımlılık eklemeye ekler.
  • veritabanı bağlantı dizesi eklerappsettings.json.

Veritabanı bağlantı dizesi

İskele aracı, dosyada appsettings.json 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 dizinde C:/Users/<user> .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, 'den Microsoft.EntityFrameworkCore.DbContexttüretilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfı olarak adlandırılır SchoolContext.

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. Hedef: _context.Students.

8 oluşum 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:
    • modelin güvenliği sağlanıp bağlamı başlatmak için kullanılmadan önce çağrılır SchoolContext .
    • Öğreticinin ilerleyen bölümlerinde varlığın Student diğer varlıklara başvuruları olacağı 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.

yapı iskelesi aracı, bağlam sınıfını bağımlılık ekleme kapsayıcısıyla 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ı dizesi adı, nesne üzerinde bir yöntem DbContextOptions çağrılarak bağlama geçirilir. Yerel geliştirme için ASP.NET Core yapılandırma sistemi veya appsettings.Development.json dosyasından bağlantı dizesi appsettings.json okur.

Veritabanı özel durum filtresini ekleme

Aşağıdaki kodda gösterildiği gibi ve UseMigrationsEndPoint ekleyinAddDatabaseDeveloperPageExceptionFilter:

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 EF geçiş hataları için geliştirme ortamında 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 EnsureCreated için bir veritabanı varsa yöntemi hiçbir işlem gerçekleştirmez. 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 EmailAddress alan ekleyin.
  • Uygulamayı çalıştırma.
  • EnsureCreated yeni ş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.

Öğretici serisinin ilerleyen bölümlerinde tarafından EnsureCreated 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.

  • içindeProgram.cs, satırından DbInitializer.Initialize 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 -Confirm
    
    
  • veritabanını silmek için ile Y yanıt verin.

  • Uygulamayı yeniden başlatın.
  • Dağıtılan 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} öğesini seçin>. Veritabanı adı, daha önce sağlanan bağlam adından ve bir tire ve GUID'den 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 modelin tablo şemasına nasıl Student eşlenip eşlenmediğini görmek için Kodu Görüntüle'ye Student tıklayı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 durumda, iş parçacıkları boşaltılana 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. Zaman uyumsuz kodla, bir işlem G/Ç'nin tamamlanmasını beklediğinde, iş parçacığı sunucunun diğer istekleri işlemek için kullanması için serbest kalı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();
}
  • async anahtar 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 Dönüş türü, devam eden çalışmayı temsil eder.
  • await anahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, zaman uyumsuz olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma yöntemine konur.
  • ToListAsync uzantı yönteminin zaman uyumsuz sürümüdür ToList .

kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:

  • Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler zaman uyumsuz olarak yürütülür. ToListAsyncBuna , , SingleOrDefaultAsyncFirstOrDefaultAsyncve SaveChangesAsyncdahildir. Gibi yalnızca bir IQueryablevar students = context.Students.Where(s => s.LastName == "Davolio")öğesini değiştiren deyimleri içermez.
  • Bağlam EF Core iş parçacığı açısından güvenli değildir: Birden çok işlemi paralel olarak gerçekleştirmeye çalışmayın.
  • Zaman uyumsuz kodun performans avantajlarından yararlanmak için, veritabanına sorgu gönderen yöntemleri çağıran EF Core kitaplık paketlerinin (sayfalama gibi) zaman uyumsuz kullandığını doğrulayın.

.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz genel bakış ve zaman uyumsuz programlama ile zaman uyumsuz programlama ve await.

Uyarı

Microsoft.Data.SqlClient'ın zaman uyumsuz uygulamasında 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.

Performans değerlendirmeleri

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 numaralandırılması, bir veritabanı özel durumu numaralandırmanın bir parçası olarak gerçekleşirse kısmen leştirilmiş bir HTTP 200 yanıtı döndürebilir.

Disk belleği, öğreticinin ilerleyen bölümlerinde ele alınmıştır.

Daha fazla bilgi için bkz . Performansla ilgili dikkat edilmesi gerekenler (EF).

Sonraki adımlar

Geliştirme için SQLite, üretim için SQL Server kullanma

Bu, ASP.NET Core Razor Pages uygulamasında Entity Framework (EF) Core'un nasıl kullanılacağını gösteren bir dizi öğreticinin ilkidir. Öğreticiler, kurgusal bir Contoso Üniversitesi için bir web sitesi oluşturur. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Öğreticide ilk olarak kod yaklaşımı kullanılır. Veritabanı ilk yaklaşımını kullanarak bu öğreticiyi izleme hakkında bilgi için bu Github sorununa bakın.

Tamamlanan uygulamayı indirin veya görüntüleyin. İndirme yönergeleri.

Önkoşullar

  • Sayfalar'ı kullanmaya yeni başladıysanız, bu sayfayı Razor başlatmadan önce Sayfaları kullanmaya Razor başlama öğretici serisini inceleyin.

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.

Sorun giderme

Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu, ASP.NET Core etiketini veya etiketini kullanarak StackOverflow.com bir soru göndermektirEF Core.

Örnek uygulama

Bu öğreticilerde oluşturulan uygulama, temel 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.

Öğrenci Dizini sayfası

Öğrenciler Düzenleme sayfası

Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Öğreticinin odak noktası, kullanıcı arabiriminin nasıl özelleştirileceği değil ASP.NET Core ile nasıl kullanılacağıdır EF Core .

İsteğe bağlı: Örnek indirmeyi derleme

Bu adım isteğe bağlıdır. Çözemezseniz tamamlanmış uygulamayı 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

  1. Visual Studio'yu başlatın ve Yeni proje oluştur'u seçin.
  2. Yeni proje oluştur iletişim kutusunda ASP.NET Çekirdek Web Uygulaması>İleri'yi seçin.
  3. Yeni projenizi yapılandırın iletişim kutusunda Proje adı için girinContosoUniversity. Büyük harfe çevirme de dahil olmak üzere bu tam adın kullanılması önemlidir, bu nedenle her namespace biri kod kopyalandığında eşleşir.
  4. Oluştur'u belirleyin.
  5. Yeni ASP.NET Core web uygulaması oluştur iletişim kutusunda şunları seçin:
    1. Açılan listelerde .NET Core ve ASP.NET Core 5.0 .
    2. ASP.NET Core Web App.
    3. OluşturYeni ASP.NET Temel Proje iletişim kutusu

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">
            &copy; 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" öğesinin "Contoso University" olarak her oluşumu. Üç oluşum vardır.
  • 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.

Sayfanın göründüğünü doğrulamak home için uygulamayı çalıştırın.

Veri modeli

Aşağıdaki bölümlerde bir veri modeli oluşturulur:

Kurs-Kayıt-Öğrenci veri modeli diyagramı

Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.

Student varlığı

Öğrenci varlık diyagramı

  • 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 classnameID adlı ID bir özelliği birincil anahtar olarak yorumlar. Bu nedenle, sınıf birincil anahtarı için Student alternatif olarak tanınan ad olur StudentID. Daha fazla bilgi için bkz EF Core . - Anahtarlar.

Enrollments özelliği bir gezinti özelliğidir. Gezinti özellikleri, bu varlıkla ilgili diğer varlıkları barındırır. Bu durumda, bir Student varlığın Enrollments ö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ı, sütunu öğrencinin kimlik değerini içeriyorsa Öğrenci satırıyla StudentID ilişkilidir. Örneğin, Bir Öğrenci satırının ID=1 olduğunu varsayalım. İlgili Kayıt satırları = 1 olacaktır StudentID . StudentID Kayıt tablosundaki bir yabancı anahtardır .

Enrollments özelliği, birden çok ilişkili Kayıt varlığı olabileceğinden olarak ICollection<Enrollment> tanımlanır. veya HashSet<Enrollment>gibi List<Enrollment> diğer koleksiyon türleri kullanılabilir. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.

Kayıt varlığı

Kayıt varlığı diyagramı

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ık kendi başına değil ID desenini classnameID kullanı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 ID classname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.

Grade özelliği bir enum'dir. Tür bildiriminden Grade sonraki soru işareti özelliğin Grade null 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 adlı <navigation property name><primary key property name>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 olarak da adlandırılabilir <primary key property name>. Örneğin, CourseID varlığın Course birincil anahtarı olduğundan CourseID.

Kurs varlığı

Kurs varlığı diyagramı

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.

özniteliği, DatabaseGenerated veritabanının oluşturmasını sağlamak yerine uygulamanın birincil anahtarı belirtmesine olanak tanır.

Derleyici hatası olmadığını doğrulamak için projeyi derleyin.

yapı iskelesi Öğrenci sayfaları

Bu bölümde, ASP.NET Core iskele aracı şunları oluşturmak için kullanılır:

  • Bir EF CoreDbContext sınıf. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır. sınıfından Microsoft.EntityFrameworkCore.DbContext türetilir.
  • Razor varlık için Student Oluşturma, Okuma, Güncelleştirme ve Silme (CRUD) işlemlerini işleyen sayfalar.
  • Sayfalar/Öğrenciler klasörü oluşturun.
  • Çözüm Gezgini Sayfalar/Öğrenciler klasörüne sağ tıklayın ve Yeni İskeleli Öğe Ekle'yi>seçin.
  • Yeni İskele Öğesi Ekle iletişim kutusunda:
    • Sol sekmede Yüklü OrtakRazor >Sayfalar'ı seçin >
    • Entity Framework (CRUD)ADD kullanan sayfalar'ı> seçin.Razor
  • Entity Framework (CRUD) kullanarak Sayfa Ekle Razor iletişim kutusunda:
    • Model sınıfı açılan listesinde Öğrenci (ContosoUniversity.Models) öğesini seçin.
    • Veri bağlamı sınıf satırında (artı) işaretini seçin + .
      • Veri bağlamı adını yerine ContosoUniversityContextile bitecek şekilde SchoolContext 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.
      • Ekle'yi seçerek Sayfa Ekle Razor iletişim kutusunu tamamlayın.

yapı iskelesi hatasıyla 'Install the package Microsoft.VisualStudio.Web.CodeGeneration.Design and try again.'başarısız olursa, iskele aracını yeniden çalıştırın veya bu GitHub sorununa bakın.

Aşağıdaki paketler otomatik olarak yüklenir:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.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:

  • Sayfalar/Öğrenciler klasöründe sayfalar oluştururRazor:
    • Create.cshtml ve Create.cshtml.cs
    • Delete.cshtml ve Delete.cshtml.cs
    • Details.cshtml ve Details.cshtml.cs
    • Edit.cshtml ve Edit.cshtml.cs
    • Index.cshtml ve Index.cshtml.cs
  • oluşturur Data/SchoolContext.cs.
  • bağlamını içindeki Startup.csbağımlılık eklemeye ekler.
  • veritabanı bağlantı dizesi eklerappsettings.json.

Veritabanı bağlantı dizesi

İskele aracı, dosyada appsettings.json 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 dizinde C:/Users/<user> .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, 'den Microsoft.EntityFrameworkCore.DbContexttüretilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfı olarak adlandırılır SchoolContext.

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. Hedef: _context.Students.

8 oluşum 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:
    • modelin güvenliği sağlanıp bağlamı başlatmak için kullanılmadan önce çağrılır SchoolContext .
    • Öğreticinin ilerleyen bölümlerinde varlığın Student diğer varlıklara başvuruları olacağı 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.

yapı iskelesi aracı, bağlam sınıfını bağımlılık ekleme kapsayıcısıyla 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ı dizesi adı, nesne üzerinde bir yöntem DbContextOptions çağrılarak bağlama geçirilir. 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 ve UseMigrationsEndPoint ekleyinAddDatabaseDeveloperPageExceptionFilter:

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 EF geçiş hataları için geliştirme ortamında 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 EnsureCreated için bir veritabanı varsa yöntemi hiçbir işlem gerçekleştirmez. 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 EmailAddress alan ekleyin.
  • Uygulamayı çalıştırma.
  • EnsureCreated yeni ş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.

Öğretici serisinin ilerleyen bölümlerinde tarafından EnsureCreated 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.

  • içindeProgram.cs, satırından DbInitializer.Initialize 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 -Confirm
    
    
  • veritabanını silmek için ile Y yanıt verin.

  • Uygulamayı yeniden başlatın.
  • Dağıtılan 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} öğesini seçin>. Veritabanı adı, daha önce sağlanan bağlam adından ve bir tire ve GUID'den 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 modelin tablo şemasına nasıl Student eşlenip eşlenmediğini görmek için Kodu Görüntüle'ye Student tıklayı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 durumda, iş parçacıkları boşaltılana 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. Zaman uyumsuz kodla, bir işlem G/Ç'nin tamamlanmasını beklediğinde, iş parçacığı sunucunun diğer istekleri işlemek için kullanması için serbest kalı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();
}
  • async anahtar 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 Dönüş türü, devam eden çalışmayı temsil eder.
  • await anahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, zaman uyumsuz olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma yöntemine konur.
  • ToListAsync uzantı yönteminin zaman uyumsuz sürümüdür ToList .

kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:

  • Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler zaman uyumsuz olarak yürütülür. ToListAsyncBuna , , SingleOrDefaultAsyncFirstOrDefaultAsyncve SaveChangesAsyncdahildir. Gibi yalnızca bir IQueryablevar students = context.Students.Where(s => s.LastName == "Davolio")öğesini değiştiren deyimleri içermez.
  • Bağlam EF Core iş parçacığı açısından güvenli değildir: Birden çok işlemi paralel olarak gerçekleştirmeye çalışmayın.
  • Zaman uyumsuz kodun performans avantajlarından yararlanmak için, veritabanına sorgu gönderen yöntemleri çağıran EF Core kitaplık paketlerinin (sayfalama gibi) zaman uyumsuz kullandığını doğrulayın.

.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz genel bakış ve zaman uyumsuz programlama ile zaman uyumsuz programlama ve await.

Performans değerlendirmeleri

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 numaralandırılması, bir veritabanı özel durumu numaralandırmanın bir parçası olarak gerçekleşirse kısmen leştirilmiş bir HTTP 200 yanıtı döndürebilir.

MaxModelBindingCollectionSize varsayılan değeri 1024'tir. Aşağıdaki kod kümeleri MaxModelBindingCollectionSize:

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

gibi MyMaxModelBindingCollectionSizeyapılandırma ayarları hakkında bilgi için bkz. Yapılandırma.

Disk belleği, öğreticinin ilerleyen bölümlerinde ele alınmıştır.

Daha fazla bilgi için bkz . Performansla ilgili dikkat edilmesi gerekenler (EF).

Entity Framework Core'un SQL Günlüğü

Günlük yapılandırması genellikle appsettings.{Environment}.json dosyalarının Logging bölümü tarafından sağlanır. SQL deyimlerini günlüğe kaydetmek için appsettings.Development.json dosyasına ekleyin"Microsoft.EntityFrameworkCore.Database.Command": "Information":

{
  "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 bkz . .NET Core ve ASP.NET Core'da günlüğe kaydetme ve bu GitHub sorunu.

Sonraki adımlar

Geliştirme için SQLite, üretim için SQL Server kullanma

Bu, ASP.NET Core Razor Pages uygulamasında Entity Framework (EF) Core'un nasıl kullanılacağını gösteren bir dizi öğreticinin ilkidir. Öğreticiler, kurgusal bir Contoso Üniversitesi için bir web sitesi oluşturur. Site öğrenci kabulü, kurs oluşturma ve eğitmen ödevleri gibi işlevleri içerir. Öğreticide ilk olarak kod yaklaşımı kullanılır. Veritabanı ilk yaklaşımını kullanarak bu öğreticiyi izleme hakkında bilgi için bu Github sorununa bakın.

Tamamlanan uygulamayı indirin veya görüntüleyin. İndirme yönergeleri.

Önkoşullar

  • Sayfalar'ı kullanmaya yeni başladıysanız, bu sayfayı Razor başlatmadan önce Sayfaları kullanmaya Razor başlama öğretici serisini inceleyin.

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.

Sorun giderme

Çözemediğiniz bir sorunla karşılaşırsanız kodunuzu tamamlanmış projeyle karşılaştırın. Yardım almanın iyi bir yolu, ASP.NET Core etiketini veya etiketini kullanarak StackOverflow.com bir soru göndermektirEF Core.

Örnek uygulama

Bu öğreticilerde oluşturulan uygulama, temel 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.

Öğrenci Dizini sayfası

Öğrenciler Düzenleme sayfası

Bu sitenin kullanıcı arabirimi stili, yerleşik proje şablonlarını temel alır. Öğreticinin odak noktası, kullanıcı arabiriminin nasıl özelleştirileceği değil, nasıl kullanılacağıdır EF Core.

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-Database
    
  • Veritabanı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'yi> 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

güncelleştirerek Pages/Shared/_Layout.cshtmlsite üst bilgisini, alt bilgisini ve menüsünü ayarlayın:

  • "ContosoUniversity" ifadesinin her örneğini "Contoso University" olarak değiştirin. Üç oluşum vardır.

  • 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">
            &copy; 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>

Sayfanın göründüğünü doğrulamak home için uygulamayı çalıştırın.

Veri modeli

Aşağıdaki bölümlerde bir veri modeli oluşturulur:

Kurs-Kayıt-Öğrenci veri modeli diyagramı

Bir öğrenci herhangi bir sayıda kursa kaydolabilir ve bir kursta kayıtlı herhangi bir sayıda öğrenci olabilir.

Student varlığı

Öğrenci varlık diyagramı

  • 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 classnameID adlı ID bir özelliği birincil anahtar olarak yorumlar. Bu nedenle, sınıf birincil anahtarı için Student alternatif olarak tanınan ad olur StudentID. Daha fazla bilgi için bkz EF Core . - Anahtarlar.

Enrollments özelliği bir gezinti özelliğidir. Gezinti özellikleri, bu varlıkla ilgili diğer varlıkları barındırır. Bu durumda, bir Student varlığın Enrollments ö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 .

Enrollments özelliği, birden çok ilişkili Kayıt varlığı olabileceğinden olarak ICollection<Enrollment> tanımlanır. veya HashSet<Enrollment>gibi List<Enrollment> diğer koleksiyon türlerini kullanabilirsiniz. Kullanıldığında ICollection<Enrollment> , EF Core varsayılan olarak bir HashSet<Enrollment> koleksiyon oluşturur.

Kayıt varlığı

Kayıt varlığı diyagramı

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ık kendi başına değil ID desenini classnameID kullanı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 ID classname kullanmak, bazı veri modeli değişikliklerinin uygulanmasını kolaylaştırır.

Grade özelliği bir enum'dir. Tür bildiriminden Grade sonraki soru işareti özelliğin Grade null 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 adlı <navigation property name><primary key property name>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 olarak da adlandırılabilir <primary key property name>. Örneğin, CourseID varlığın Course birincil anahtarı olduğundan CourseID.

Kurs varlığı

Kurs varlığı diyagramı

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.

özniteliği, DatabaseGenerated veritabanının oluşturmasını sağlamak yerine uygulamanın birincil anahtarı belirtmesine olanak tanır.

Derleyici hatası olmadığını doğrulamak için projeyi derleyin.

yapı iskelesi Öğrenci sayfaları

Bu bölümde, oluşturmak için ASP.NET Core iskele aracını kullanacaksınız:

  • Bağlam EF Coresınıfı. Bağlam, belirli bir veri modeli için Entity Framework işlevselliğini koordine eden ana sınıftır. sınıfından Microsoft.EntityFrameworkCore.DbContext türetilir.
  • Razor varlık için Student Oluş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 Sayfalar/Öğrenciler klasörüne sağ tıklayın ve Yeni İskeleli Öğe Ekle'yi>seçin.
  • yapı iskelesi ekle iletişim kutusunda Entity Framework (CRUD)>ADD kullanan sayfalar'ı seçin.Razor
  • Entity Framework (CRUD) kullanarak Sayfa Ekle Razor iletişim kutusunda:
    • Model sınıfı açılan listesinde Öğrenci (ContosoUniversity.Models) öğesini seçin.
    • Veri bağlamı sınıf satırında (artı) işaretini seçin + .
    • ContosoUniversity.Models.ContosoUniversityContext olan veri bağlamı adını ContosoUniversity.Data.SchoolContext olarak değiştirin.
    • Ekle'yi seçin.

Aşağıdaki paketler otomatik olarak yüklenir:

  • Microsoft.VisualStudio.Web.CodeGeneration.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.Extensions.Logging.Debug
  • Microsoft.EntityFrameworkCore.Tools

Önceki adımla ilgili bir sorun yaşıyorsanız projeyi derleyin ve iskele adımını yeniden deneyin.

yapı iskelesi işlemi:

  • Sayfalar/Öğrenciler klasöründe sayfalar oluştururRazor:
    • Create.cshtml ve Create.cshtml.cs
    • Delete.cshtml ve Delete.cshtml.cs
    • Details.cshtml ve Details.cshtml.cs
    • Edit.cshtml ve Edit.cshtml.cs
    • Index.cshtml ve Index.cshtml.cs
  • oluşturur Data/SchoolContext.cs.
  • bağlamını içindeki Startup.csbağımlılık eklemeye ekler.
  • veritabanı bağlantı dizesi eklerappsettings.json.

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 dizinde C:/Users/<user> .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, 'den Microsoft.EntityFrameworkCore.DbContexttüretilir. Bağlam, veri modeline hangi varlıkların dahil olduğunu belirtir. Bu projede sınıfı olarak adlandırılır SchoolContext.

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. yapı iskelesi aracı birStudent DBSet oluşturduğundan, bu adım bunu çoğul Studentsolarak 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 oluşum 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.

yapı iskelesi aracı, bağlam sınıfını bağımlılık ekleme kapsayıcısıyla 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ı dizesi adı, nesne üzerinde bir yöntem DbContextOptions çağrılarak bağlama geçirilir. 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 EnsureCreated için bir veritabanı varsa yöntemi hiçbir işlem gerçekleştirmez. 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 EmailAddress alan ekleyin.
  • Uygulamayı çalıştırma.
  • EnsureCreated yeni ş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 serisinin ilerleyen bölümlerinde, tarafından EnsureCreated oluşturulan veritabanını siler ve bunun yerine geçişleri 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.

  • içinde Program.csçağrısını EnsureCreated bir DbInitializer.Initialize çağrı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.

  • Dağıtılan 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} öğesini seçin>. Veritabanı adı, daha önce sağladığınız bağlam adından ve bir tire ve GUID'den 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 modelin tablo şemasına nasıl Student eşlenip eşlenmediğini görmek için Kodu Görüntüle'ye Student tıklayı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 durumda, iş parçacıkları boşaltılana kadar sunucu yeni istekleri işleyemez. Zaman uyumlu kodla, G/Ç'nin tamamlanmasını beklediği için aslında herhangi bir iş yapmadıkları sırada birçok iş parçacığı bağlanabilir. Zaman uyumsuz kodla, bir işlem G/Ç'nin tamamlanmasını beklediğinde, iş parçacığı sunucunun diğer istekleri işlemek için kullanması için serbest kalı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<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();
}
  • async anahtar 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.
  • await anahtar sözcüğü, derleyicinin yöntemini iki bölüme ayırmasına neden olur. İlk bölüm, zaman uyumsuz olarak başlatılan işlemle sona erer. İkinci bölüm, işlem tamamlandığında çağrılan bir geri çağırma yöntemine konur.
  • ToListAsync uzantı yönteminin zaman uyumsuz sürümüdür ToList .

kullanan EF Corezaman uyumsuz kod yazarken dikkat edilmesi gereken bazı şeyler:

  • Yalnızca veritabanına sorgu veya komut gönderilmesine neden olan deyimler zaman uyumsuz olarak yürütülür. ToListAsyncBuna , , SingleOrDefaultAsyncFirstOrDefaultAsyncve SaveChangesAsyncdahildir. Gibi yalnızca bir IQueryablevar students = context.Students.Where(s => s.LastName == "Davolio")öğesini değiştiren deyimleri içermez.
  • Bağlam EF Core iş parçacığı açısından güvenli değildir: Birden çok işlemi paralel olarak gerçekleştirmeye çalışmayın.
  • Zaman uyumsuz kodun performans avantajlarından yararlanmak için, veritabanına sorgu gönderen yöntemleri çağıran EF Core kitaplık paketlerinin (sayfalama gibi) zaman uyumsuz kullandığını doğrulayın.

.NET'te zaman uyumsuz programlama hakkında daha fazla bilgi için bkz . Zaman uyumsuz genel bakış ve zaman uyumsuz programlama ile zaman uyumsuz programlama ve await.

Sonraki adımlar