카테고리 없음

C# EfCore 도큐먼트 정독 후 숙지사항 정리

daniel_lab 2023. 7. 22. 22:30

EfCore에서 DB와의 연결은 DbContext라는 객체를 통해 구현된다. 이 객체가 생성되고 disposed될때까지가 lifetime 이라고 보면 된다. 이 DbContext는 unit-of-work로 정의되는 단위동안 사용되도록 설계되었고(보통 매우 짧은 시간) MS에서 밝히는 보통의 unit-of-work 란 아래와 같다. 

 

1. DbContext 객체가 생성된다

2. entity instances 들이 tracking 된다. tracking되는 상황은 아래와 같다.

- query로 리턴된 entity 객체들

- add 되거나 attached 된 객체들

3. 위 tracking 객체들에 변경이 가해진다

4. savechanges 에 의해 변경이 database에 가해진다

5. DbContext가 disposed 된다

 

## DbContext 생성주기를 Controller의 request 주기와 일치시키기

아래처럼 service등록 단계에서 AddDbContext 메소드를 통해 DbContext를 상속한 서브클래스를 등록한다. 이렇게되면 ApplicationDbContext가 scoped service로 등록된다(Controller에서 DI 받아 사용하게 되면 각각의 API request와 생존주기가 동기화)

동시에 옵션을 설정하게 되는데, 이 옵션정보에는 DB 연결정보가 들어간다.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddDbContext<ApplicationDbContext>(
        options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
}

 

이렇게 설정한 옵션정보는 DbContext에 전달될 수 있어야 하는데, 아래와 같이 ApplicationDbContext의 생성자에는 옵션정보를 DbContext에 전달하는 생성자유형이 필요하다.

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

 

## DbContext 가 thread-safe 하지 않은 것과 관련된 이슈

EfCore에서 하나의 DbContext로 복수개의 요청이 parallel하게 진행되는것이 지원되지 않는다. 즉, 여러 스레드를 통해 동시에 하나의 DbContext를 통한 요청은 안된다는 의미. 동시에 여러 요청을 병렬로 진행하고 싶다면 서로 다른 DbContext로 동시에 진행해야 한다.