Megosztás a következőn keresztül:


ASP.NET Core-Blazor az Entity Framework Core-nal (EF Core)

Jegyzet

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információ: .NET és .NET Core támogatási szabályzat. A jelenlegi kiadás megtekintéséhez nézze meg ennek a cikknek a .NET 9-es verzióját .

Ez a cikk a Entity Framework Core (EF Core) kiszolgálóoldali Blazor-alkalmazásokban való használatát ismerteti.

A kiszolgálóoldali Blazor állapotalapú alkalmazás-keretrendszer. Az alkalmazás folyamatos kapcsolatot tart fenn a kiszolgálóval, és a felhasználó állapota a kiszolgáló memóriájában van egy kapcsolatcsoportban. A felhasználói állapotra példa az függőséginjektálási (DI) szolgáltatáspéldányokban tárolt adatok, amelyek hatóköre a ciklusra terjed ki. Az Blazor által biztosított egyedi alkalmazásmodell speciális megközelítést igényel az Entity Framework Core használatához.

Jegyzet

Ez a cikk a EF Core problémával foglalkozik kiszolgálóoldali Blazor-alkalmazásokban. Blazor WebAssembly alkalmazások egy WebAssembly tesztkörnyezetben futnak, amely megakadályozza a legtöbb közvetlen adatbázis-kapcsolatot. EF Core futtatása Blazor WebAssembly-ban/-ben túlesik a jelen cikk keretein.

Ez az útmutató azokra az összetevőkre vonatkozik, amelyek interaktív kiszolgálóoldali renderelést (interaktív SSR-t) alkalmaznak egy Blazor Web App.

Ez az útmutató egy üzemeltetett Server-megoldás vagy Blazor WebAssembly-alkalmazás Blazor Server projektére vonatkozik.

Az éles alkalmazásokhoz szükséges biztonságos hitelesítési folyamat

Ez a cikk olyan helyi adatbázis használatára vonatkozik, amely nem igényel felhasználói hitelesítést. Az éles alkalmazásoknak az elérhető legbiztonságosabb hitelesítési folyamatot kell használniuk. Az üzembe helyezett teszt- és éles Blazor-alkalmazások hitelesítéséről további információt a BlazorBiztonsági és Identity csomópontcímű cikkben talál.

A Microsoft Azure-szolgáltatások esetében felügyelt identitások használatát javasoljuk. A felügyelt identitások biztonságosan hitelesíthetők az Azure-szolgáltatásokban anélkül, hogy hitelesítő adatokat tárolnak az alkalmazáskódban. További információ:

Blazor filmadatbázis-alkalmazás oktatóanyagának létrehozása

Egy alkalmazás építésének, amely a(z) EF Core-ot használja adatbázis-műveletekhez, oktatóanyagához lásd a(z) Blazor filmadatbázis-alkalmazás (áttekintés)című részt. Az oktatóanyag bemutatja, hogyan hozhat létre olyan Blazor Web App, amely képes filmek megjelenítésére és kezelésére egy filmadatbázisban.

Adatbázis-hozzáférés

EF Core egy DbContext-re támaszkodik a adatbázis-hozzáférés konfigurálásának eszközeként, és munkaegységként működik. EF Core AddDbContext bővítményt biztosít ASP.NET Core-alkalmazásokhoz, amelyek a környezetet hatókörű szolgáltatásként regisztrálják. A kiszolgálóoldali Blazor alkalmazásokban a hatóköralapú szolgáltatásregisztrációk problémásak lehetnek, mivel a példány meg van osztva a felhasználó kapcsolatcsoportján belüli összetevők között. DbContext nem szálbiztos, és nem tervezték egyidejű használatra. A meglévő élettartamok az alábbi okok miatt nem megfelelőek:

  • Singleton az alkalmazás összes felhasználója között megosztja az állapotot, és nem megfelelő egyidejű használathoz vezet.
  • Korlátozott hatáskörű (az alapértelmezett) hasonló problémát jelent a komponensek között ugyanazon felhasználó számára.
  • Átmeneti esetén kérésenként új példány jön létre; azonban, mivel a szoftver összetevők hosszú élettartamúak lehetnek, ez hosszabb élettartamú kontextust eredményezhet, mint amennyi szándékolt.

Az alábbi javaslatok a EF Core kiszolgálóoldali Blazor-alkalmazásokban való használatának konzisztens megközelítésére szolgálnak.

  • Érdemes lehet műveletenként egy környezetet használni. A környezet a gyors, kis erőforrás-igényű példányosításhoz lett kialakítva.

    using var context = new ProductsDatabaseContext();
    
    return await context.Products.ToListAsync();
    
  • Több egyidejű művelet megelőzéséhez használjon jelölőt:

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

    Helyezze el az adatbázis-műveleteket a Loading = true; sor után a try blokkban.

    A szálbiztonság nem probléma, ezért a betöltési logika nem igényel adatbázisrekordok zárolását. A betöltési logika a felhasználói felület vezérlőinek letiltására szolgál, hogy a felhasználók ne válasszanak véletlenül gombokat vagy frissítsenek mezőket az adatok beolvasása közben.

  • Ha van rá esély, hogy több szál is hozzáfér ugyanahhoz a kódblokkhoz, szúrjon be egy gyári, és műveletenként hozzon létre egy új példányt. Ellenkező esetben az injektálás és a környezet használata általában elegendő.

  • Az változáskövetési vagy egyidejűség-vezérlésia környezet hatókörét az összetevőélettartamára .

Új DbContext példányok

Az új DbContext-példányok létrehozásának leggyorsabb módja a new használata egy új példány létrehozásához. Vannak azonban olyan forgatókönyvek, amelyek további függőségek feloldását igénylik:

Figyelmeztetés

Ne tárolja az alkalmazás titkos kulcsait, kapcsolati sztringeket, hitelesítő adatokat, jelszavakat, személyes azonosítószámokat (PIN-eket), titkos C#/.NET-kódot vagy titkos kulcsokat/jogkivonatokat az ügyféloldali kódban, amely mindig nem biztonságos. Tesztelési/előkészítési és éles környezetekben a kiszolgálóoldali Blazor kód- és webes API-knak biztonságos hitelesítési folyamatokat kell használniuk, amelyek nem őrzik meg a hitelesítő adatokat a projektkódban vagy a konfigurációs fájlokban. A helyi fejlesztési tesztelésen kívül javasoljuk, hogy kerülje a környezeti változók bizalmas adatok tárolására való használatát, mivel a környezeti változók nem a legbiztonságosabb megközelítések. A helyi fejlesztési teszteléshez a Secret Manager eszköz ajánlott bizalmas adatok védelméhez. További információ: Bizalmas adatok és hitelesítő adatok biztonságos karbantartása.

A függőségekkel rendelkező új DbContext létrehozásának ajánlott módszere egy gyár használata. EF Core a .NET 5-ös vagy újabb verziójában egy beépített gyárat biztosít az új környezetek létrehozásához.

A .NET 5 előtti .NET-verziókban használja a következőket DbContextFactory:

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

Az előző gyárban:

Az alábbi példa konfigurálja a SQLite-ot, és engedélyezi az adatnaplózást egy névjegyeket kezelő alkalmazásban. A kód egy bővítménymetódus (AddDbContextFactory) használatával konfigurálja az adatbázis-előállítót a DI-hez, és alapértelmezett beállításokat biztosít:

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"));

A gyár komponenseket épít be az új DbContext példányok létrehozásához.

Az adatbázis-környezet hozzárendelése egy összetevő metódusához.

A gyárat a komponensbe injektálják.

@inject IDbContextFactory<ContactContext> DbFactory

Hozzon létre egy DbContext egy metódushoz a factory (DbFactory) használatával:

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

Határozd meg az adatbázis-környezet hatókörét az összetevő élettartamához

Létrehozhat egy olyan DbContext, amely egy összetevő teljes élettartama alatt létezik. Így munkaegységként használhatja, és kihasználhatja a beépített funkciókat, például a változáskövetést és az egyidejűségi megoldást.

Implementálja IDisposable, és injektálja a factory-t az összetevőbe:

@implements IDisposable
@inject IDbContextFactory<ContactContext> DbFactory

Hozzon létre egy tulajdonságot a DbContext:

private ContactContext? Context { get; set; }

A OnInitializedAsynclétrehozásához a DbContext felülírva van.

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

A DbContext ártalmatlanításra kerül, amikor az összetevőt megsemmisítik.

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

Bizalmas adatnaplózás engedélyezése

EnableSensitiveDataLogging alkalmazásadatokat tartalmaz kivételüzenetekben és keretrendszernaplózásban. A naplózott adatok tartalmazhatják az entitáspéldányok tulajdonságaihoz rendelt értékeket és az adatbázisba küldött parancsok paraméterértékeit. Az adatok EnableSensitiveDataLogging naplózása biztonsági kockázatot jelent, mivel jelszavakat és más személyazonosításra alkalmas adatokat (PII) tehet közzé, amikor naplózza az adatbázison végrehajtott SQL-utasításokat.

Javasoljuk, hogy csak helyi fejlesztéshez és teszteléshez engedélyezze EnableSensitiveDataLogging a következőket:

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

További erőforrások