ASP.NET Core Blazor ile Entity Framework Core (EF Core)

Not

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.

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

Bu makalede, sunucu tarafı EF Core uygulamalarda Entity Framework Core'un ()Blazoraçıklanmaktadır.

Sunucu taraflı Blazor, durum bilgisi tutan bir uygulama çerçevesidir. Uygulama sunucuyla devam eden bir bağlantı tutar ve kullanıcının durumu sunucunun belleğinde bir bağlantı hattında tutulur. Kullanıcı durumuna bir örnek, devre kapsamındaki bağımlılık ekleme (DI) hizmet örneklerinde tutulan verilerdir. Blazor’nin sunduğu benzersiz uygulama modeli, Entity Framework Core’u kullanmak için özel bir yaklaşım gerektirir.

Not

Bu makale, sunucu taraflı Blazor uygulamalarda EF Core konusunu ele almaktadır. Blazor WebAssembly uygulamaları, doğrudan veritabanı bağlantılarının çoğunu engelleyen bir WebAssembly yalıtılmış ortamında çalışır. Blazor WebAssembly içinde EF Core çalıştırmak bu makalenin kapsamının dışındadır.

Bu kılavuz, Blazor Web App içinde etkileşimli sunucu tarafı işlemeyi (etkileşimli SSR) benimseyen bileşenler için geçerlidir.

Bu kılavuz barındırılan Server bir çözümün Blazor WebAssembly veya Blazor Server uygulamanın projesi için geçerlidir.

Üretim uygulamaları için güvenli kimlik doğrulama akışı gerekiyor

Bu makale, kullanıcı kimlik doğrulaması gerektirmeyen bir yerel veritabanı kullanımıyla ilgili. Üretim uygulamaları kullanılabilir en güvenli kimlik doğrulama akışını kullanmalıdır. Dağıtılan test ve üretim Blazor uygulamaları için kimlik doğrulaması hakkında daha fazla bilgi için BlazorGüvenlik ve Identity düğümündeki makalelere bakın.

Microsoft Azure hizmetleri için yönetilen kimlikleri kullanmanızı öneririz. Yönetilen kimlikler, kimlik bilgilerini uygulama kodunda depolamadan Azure hizmetlerine güvenli bir şekilde kimlik doğrulaması sağlar. Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:

Bir Blazor film veritabanı uygulaması oluşturma eğitimi

Veritabanı işlemleri için kullanan bir uygulama oluşturma öğretici deneyimi için bkz. film veritabanı uygulaması derleme (Genel Bakış) . Bu öğretici, bir film veritabanındaki filmleri görüntüleyip yönetebilen bir Blazor Web App nasıl oluşturacağınızı gösterir.

Veritabanı erişimi

EF Core, veritabanı erişimini yapılandırmak ve iş birimi görevi görmek için bir DbContext kullanır. EF Core, bağlamı kapsamlı bir hizmet olarak kaydeden ASP.NET Core uygulamaları için AddDbContext uzantısını sağlar. Sunucu tarafı Blazor uygulamalarda, scoped hizmet kayıtları sorunlu olabilir çünkü örnek kullanıcının devresi içindeki bileşenler arasında paylaşılır. DbContext iş parçacığı güvenli değildir ve eşzamanlı kullanım için tasarlanmamıştır. Mevcut ömürler şu nedenlerden dolayı uygun değildir:

  • Singleton, uygulamanın tüm kullanıcıları arasında durumunu paylaşır ve uygun olmayan eşzamanlı kullanıma yol açar.
  • Kapsamı belirlenmiş (varsayılan), aynı kullanıcı için bileşenler arasında benzer bir soruna yol açar.
  • Geçici kullanım, istek başına yeni bir örnek oluşturur; ancak bileşenler uzun ömürlü olabildiğinden, bu durum amaçlanandan daha uzun ömürlü bir bağlam oluşturur.

Aşağıdaki öneriler, EF Core öğesinin sunucu taraflı Blazor uygulamalarında kullanımına yönelik tutarlı bir yaklaşım sunmak için tasarlanmıştır.

  • İşlem başına bir bağlam kullanmayı göz önünde bulundurun. Bağlam, hızlı ve düşük ek yükle örnek oluşturma için tasarlanmıştır:

    using var context = new ProductsDatabaseContext();
    
    return await context.Products.ToListAsync();
    
  • Birden çok eşzamanlı işlemi önlemek için bir bayrak kullanın:

    if (Loading)
    {
        return;
    }
    
    try
    {
        Loading = true;
    
        ...
    }
    finally
    {
        Loading = false;
    }
    

    Veritabanı işlemlerini Loading = true; bloğundaki try satırının arkasına yerleştirin.

    İş parçacığı güvenliği önemli değildir, bu nedenle mantığın yüklenmesi için veritabanı kayıtlarının kilitlenmesi gerekmez. Yükleme mantığı kullanıcı arabirimi denetimlerini devre dışı bırakmak için kullanılır, böylece kullanıcılar yanlışlıkla düğmeler seçmez veya veriler getirilirken alanları güncelleştirmez.

  • Birden çok iş parçacığının aynı kod bloğuna erişme olasılığı varsa, bir factory enjekte edin ve işlem başına yeni bir örnek oluşturun. Aksi takdirde, bağlamı enjekte etmek ve kullanmak genellikle yeterlidir.

  • EF Core'nin değişiklik izleme veya eşzamanlılık denetiminden yararlanan daha uzun süreli işlemler için, bağlamı bileşenin kullanım ömrüyle sınırlandırın.

Yeni DbContext örnekleri

Yeni DbContext örnek oluşturmanın en hızlı yolu, new kullanarak yeni bir örnek oluşturmaktır. Ancak, ek bağımlılıkların çözülmesini gerektiren senaryolar vardır:

Uyarı

Uygulama gizli dizilerini, bağlantı dizelerini, kimlik bilgilerini, parolaları, kişisel kimlik numaralarını (PIN'leri), özel C#/.NET kodunu veya özel anahtarları/belirteçleri istemci tarafı kodunda depolamayın; bu kod her zaman güvenli değildir. Test/hazırlama ve üretim ortamlarında, sunucu tarafı Blazor kod ve web API'leri, proje kodu veya yapılandırma dosyalarında kimlik bilgilerinin saklanmasını önleyen güvenli kimlik doğrulama akışları kullanmalıdır. Yerel geliştirme testlerinin dışında, ortam değişkenleri en güvenli yaklaşım olmadığından hassas verileri depolamak için ortam değişkenlerinin kullanılmasından kaçınmanızı öneririz. Yerel geliştirme testleri için, hassas verilerin güvenliğini sağlamak amacıyla Secret Manager aracı önerilir. Daha fazla bilgi için bkz. Hassas verileri ve kimlik bilgilerini güvenli bir şekilde sürdürme.

Bağımlılıklarla yeni bir DbContext oluşturmanın önerilen yaklaşımı bir fabrika kullanmaktır. EF Core in .NET 5 veya üzeri, yeni bağlamlar oluşturmak için yerleşik bir oluşturma mekanizması sağlar.

.NET'in .NET 5 öncesi sürümlerinde aşağıdakini DbContextFactorykullanın:

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace BlazorServerDbContextExample.Data
{
    public class DbContextFactory<TContext> 
        : IDbContextFactory<TContext> where TContext : DbContext
    {
        private readonly IServiceProvider provider;

        public DbContextFactory(IServiceProvider provider)
        {
            this.provider = provider ?? throw new ArgumentNullException(
                $"{nameof(provider)}: You must configure an instance of " +
                "IServiceProvider");
        }

        public TContext CreateDbContext() => 
            ActivatorUtilities.CreateInstance<TContext>(provider);
    }
}

Önceki fabrikada:

Aşağıdaki örnek, SQLite'i yapılandırır ve kişileri yöneten bir uygulamada veri günlüğü kaydını etkinleştirir. Kod, veritabanı fabrikasını DI için yapılandırmak ve varsayılan seçenekleri sağlamak için bir uzantı yöntemi (AddDbContextFactory) kullanır:

builder.Services.AddDbContextFactory<ContactContext>(opt =>
    opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));
services.AddDbContextFactory<ContactContext>(opt =>
    opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));

Fabrika, yeni DbContext örnekleri oluşturmak için bileşenlere eklenir.

Veritabanı bağlamı kapsamını bir bileşen yöntemiyle kapsama

Fabrika bileşene eklenir:

@inject IDbContextFactory<ContactContext> DbFactory

Fabrikayı kullanarak bir yöntem için DbContext oluşturma (DbFactory):

private async Task DeleteContactAsync()
{
    using var context = DbFactory.CreateDbContext();

    if (context.Contacts is not null)
    {
        var contact = await context.Contacts.FirstAsync(...);

        if (contact is not null)
        {
            context.Contacts?.Remove(contact);
            await context.SaveChangesAsync();
        }
    }
}

Veritabanı bağlamının kapsamını bileşenin kullanım ömrüne göre belirleme

Bir bileşenin ömrü boyunca var olan bir DbContext oluşturmak isteyebilirsiniz. Bu, bunu bir iş birimi olarak kullanmanıza ve değişiklik izleme ve eşzamanlılık çözümlemesi gibi yerleşik özelliklerden yararlanmanıza olanak tanır.

IDisposable uygulayın ve fabrikayı bileşene enjekte edin.

@implements IDisposable
@inject IDbContextFactory<ContactContext> DbFactory

DbContextiçin bir özellik oluşturun:

private ContactContext? Context { get; set; }

OnInitializedAsyncoluşturmak için DbContext geçersiz kılınmış:

protected override async Task OnInitializedAsync()
{
    Context = DbFactory.CreateDbContext();
}

bileşen atıldığında DbContext atılır:

public void Dispose() => Context?.Dispose();

Hassas veri günlüğünü etkinleştir

EnableSensitiveDataLogging, uygulama verilerini özel durum iletilerine ve çerçeve günlüğüne ekler. Günlüğe kaydedilen veriler, varlık örneklerinin özelliklerine atanan değerleri ve veritabanına gönderilen komutlar için parametre değerlerini içerebilir. EnableSensitiveDataLogging ile veri günlüğe kaydetmek, veritabanına karşı yürütülen SQL deyimlerini günlüğe kaydederken parolaları ve diğer Kişisel Olarak Tanımlanabilir Bilgileri (PII) açığa çıkarabileceği için bir güvenlik riskidir.

EnableSensitiveDataLogging yalnızca yerel geliştirme ve test için etkinleştirmenizi öneririz:

if (builder.Environment.IsDevelopment())
{
    services.AddDbContextFactory<ContactContext>(opt =>
        opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db")
        .EnableSensitiveDataLogging());
}
else
{
    services.AddDbContextFactory<ContactContext>(opt =>
        opt.UseSqlite($"Data Source={nameof(ContactContext.ContactsDb)}.db"));
}