Entity Framework Core(Blazor)를 사용한 ASP.NET Core EF Core
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
Important
이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.
현재 릴리스는 이 문서의 .NET 9 버전을 참조 하세요.
이 문서에서는 서버 쪽 EF Core 앱에서 Entity Framework Core()Blazor방법을 설명합니다.
서버 쪽 Blazor 은 상태 저장 앱 프레임워크입니다. 앱은 서버에 대한 지속적인 연결을 유지하고, 사용자 상태는 ‘회로’의 서버 메모리에 저장됩니다. 사용자 상태의 한 예는 회로로 범위가 지정된 DI(종속성 주입) 서비스 인스턴스에 저장된 데이터입니다. Blazor에서 제공하는 고유한 애플리케이션 모델을 사용하려면 Entity Framework Core를 사용하는 특별한 방법이 필요합니다.
참고 항목
이 문서에서는 서버 쪽 EF Core 앱에 대해 설명합니다Blazor. Blazor WebAssembly 앱은 대부분 직접 데이터베이스 연결을 방지하는 WebAssembly 샌드박스에서 실행됩니다. EF Core에서 Blazor WebAssembly를 실행하는 것은 이 문서에서 다루지 않습니다.
이 지침은 .에서 대화형 서버 쪽 렌더링(대화형 SSR)을 채택하는 구성 요소에 Blazor Web App적용됩니다.
이 지침은 호스트 Server
된 Blazor WebAssembly 솔루션 또는 Blazor Server 앱의 프로젝트에 적용됩니다.
프로덕션 앱에 필요한 보안 인증 흐름
이 문서는 사용자 인증이 필요하지 않은 로컬 데이터베이스의 사용과 관련이 있습니다. 프로덕션 앱은 사용 가능한 가장 안전한 인증 흐름을 사용해야 합니다. 배포된 테스트 및 프로덕션 Blazor 앱의 인증에 대한 자세한 내용은 보안 및 Blazor 노드Identity문서를 참조하세요.
Microsoft Azure 서비스의 경우 관리 ID를 사용하는 것이 좋습니다. 관리 ID는 앱 코드에 자격 증명을 저장하지 않고 Azure 서비스에 안전하게 인증합니다. 자세한 내용은 다음 리소스를 참조하세요.
- Azure 리소스에 대한 관리 ID란? (Microsoft Entra 설명서)
- Azure 서비스 설명서
Blazor 동영상 데이터베이스 앱 빌드 자습서
데이터베이스 작업에 EF Core 사용하는 앱을 빌드하는 자습서 환경은 Blazor 동영상 데이터베이스 앱 빌드(개요)참조하세요. 이 자습서에서는 영화 데이터베이스에서 Blazor Web App 영화를 표시하고 관리할 수 있는 동영상을 만드는 방법을 보여줍니다.
데이터베이스 액세스
EF Core는 데이터베이스 액세스를 구성하고 작업DbContext하는 수단으로 사용합니다. EF Core는 컨텍스트를 AddDbContext 범위가 지정된 서비스로 등록하는 ASP.NET Core 앱에 대한 확장을 제공합니다. 서버 쪽 Blazor 앱에서 범위가 지정된 서비스 등록은 인스턴스가 사용자의 회로 내의 구성 요소 간에 공유되기 때문에 문제가 될 수 있습니다. DbContext는 스레드로부터 안전하지 않고 동시 사용을 위해 설계되지 않았습니다. 기존 수명은 다음과 같은 이유로 적합하지 않습니다.
- Singleton은 앱의 모든 사용자에 대한 상태를 공유하고 부적절한 동시 사용을 초래합니다.
- 범위 지정(기본값)은 동일한 사용자에 대한 구성 요소 간에 유사한 문제를 초래합니다.
- 임시는 요청별로 새 인스턴스를 생성하지만 구성 요소가 오래 지속될 수 있으므로 의도한 것보다 수명이 긴 컨텍스트가 생성됩니다.
다음 권장 사항은 서버 쪽 EF Core 앱에서 사용하기 Blazor 위한 일관된 접근 방식을 제공하도록 설계되었습니다.
작업당 하나의 컨텍스트를 사용하는 것이 좋습니다. 이 컨텍스트는 빠르고 낮은 오버헤드 인스턴스화를 위해 설계되었습니다.
using var context = new ProductsDatabaseContext(); return await context.Products.ToListAsync();
플래그를 사용하여 여러 동시 작업을 방지합니다.
if (Loading) { return; } try { Loading = true; ... } finally { Loading = false; }
데이터베이스 작업을
Loading = true;
줄 뒤의try
블록에 배치합니다.스레드 보안은 문제가 되지 않으므로 논리를 로드해도 데이터베이스 레코드를 잠글 필요가 없습니다. 논리 로드는 데이터를 가져오는 동안 사용자가 실수로 단추를 선택하거나 필드를 업데이트하지 않도록 UI 컨트롤을 사용하지 않도록 설정하는 데 사용됩니다.
여러 스레드가 동일한 코드 블록에 액세스할 가능성이 있는 경우 센터를 삽입하고 작업당 새 인스턴스를 만듭니다. 그렇지 않으면 일반적으로 컨텍스트를 삽입하고 사용하는 것으로 충분합니다.
EF Core의 변경 내용 추적 또는 동시성 제어를 활용하는 장기 작업의 경우, 컨텍스트의 범위를 구성 요소의 수명으로 지정합니다.
새 DbContext
인스턴스
새 DbContext 인스턴스를 만드는 가장 빠른 방법은 new
를 사용하여 새 인스턴스를 만드는 것입니다. 하지만 추가 종속성을 확인해야 하는 시나리오가 있습니다.
-
DbContextOptions
를 사용하여 컨텍스트를 구성합니다. - DbContext을 사용하는 경우와 같이 Identity당 연결 문자열을 사용합니다. 자세한 내용은 다중 테넌트(EF Core 문서)를 참조하세요.
Warning
앱 비밀, 연결 문자열, 자격 증명, 암호, PIN(개인 식별 번호), 개인 C#/.NET 코드 또는 프라이빗 키/토큰을 항상 안전하지 않은 클라이언트 쪽 코드에 저장하지 마세요. 테스트/스테이징 및 프로덕션 환경에서 서버 쪽 Blazor 코드 및 웹 API는 프로젝트 코드 또는 구성 파일 내에서 자격 증명을 유지 관리하지 않는 보안 인증 흐름을 사용해야 합니다. 로컬 개발 테스트 외에는 환경 변수가 가장 안전한 방법이 아니므로 환경 변수를 사용하여 중요한 데이터를 저장하는 것을 피하는 것이 좋습니다. 로컬 개발 테스트의 경우 중요한 데이터를 보호하기 위해 Secret Manager 도구를 사용하는 것이 좋습니다. 자세한 내용은 중요한 데이터 및 자격 증명을 안전하게 유지 관리하세요.
종속성을 사용하여 새 DbContext를 만드는 권장 접근법은 팩터리를 사용하는 것입니다. EF Core 5.0 이상에서는 새 컨텍스트를 만들기 위한 기본 제공 팩터리를 제공합니다.
5.0 이전 버전의 .NET에서는 다음 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);
}
}
이전 팩터리에서
- ActivatorUtilities.CreateInstance은 서비스 공급자를 통해 종속 항목을 충족합니다.
- IDbContextFactory<TContext> EF Core ASP.NET Core 5.0 이상에서 사용할 수 있으므로 이전 인터페이스는 ASP.NET Core 3.x에만 필요합니다.
다음 예제에서는 SQLite 구성하고 연락처를 관리하는 앱에서 데이터 로깅을 사용하도록 설정합니다. 이 코드는 확장 메서드(AddDbContextFactory)를 사용하여 DI용 데이터베이스 팩터리를 구성하고 기본 옵션을 제공합니다.
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"));
팩터리는 구성 요소에 삽입되어 새 DbContext 인스턴스를 만듭니다.
구성 요소 메서드로 데이터베이스 컨텍스트 범위 지정
팩토리 패턴이 구성 요소에 삽입됩니다.
@inject IDbContextFactory<ContactContext> DbFactory
팩터리(DbFactory
)를 사용하여 메서드를 위한 DbContext을 만듭니다.
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();
}
}
}
구성 요소의 수명까지 데이터베이스 컨텍스트 범위 지정
구성 요소의 수명 동안 존재하는 DbContext를 만들 수 있습니다. 그러면 해당 인스턴스를 작업 단위로 사용하고 변경 내용 추적, 동시성 확인과 같은 기본 제공 기능을 활용할 수 있습니다.
IDisposable 구현하고 구성 요소에 팩터리를 삽입합니다.
@implements IDisposable
@inject IDbContextFactory<ContactContext> DbFactory
DbContext의 속성을 설정합니다.
private ContactContext? Context { get; set; }
OnInitializedAsync
이(가) 재정의되어 DbContext을(를) 생성합니다.
protected override async Task OnInitializedAsync()
{
Context = DbFactory.CreateDbContext();
}
구성 요소가 삭제되면 DbContext 삭제됩니다.
public void Dispose() => Context?.Dispose();
중요한 데이터 로깅 사용
EnableSensitiveDataLogging에는 예외 메시지 및 프레임워크 로깅의 애플리케이션 데이터가 포함됩니다. 로깅된 데이터에는 엔터티 인스턴스 속성에 할당된 값과 데이터베이스로 전송된 명령의 매개 변수 값이 포함될 수 있습니다. 데이터 EnableSensitiveDataLogging 로깅은 데이터베이스에 대해 실행된 SQL 문을 기록할 때 암호 및 기타 PII(개인 식별 정보)를 노출할 수 있으므로 보안 위험입니다.
EnableSensitiveDataLogging은 개발 및 테스트 용도로만 사용하는 것이 좋습니다.
#if DEBUG
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"));
#endif
추가 리소스
ASP.NET Core