2022. 9. 27. 15:30

프로젝트를 진행하다 보면 여러 가지 이유로 컨텍스트(Context)를 분리해서 관리할 필요가 있죠.

 

권장은 하나의 DB에 하나의 컨텍스트를 사용하는 것이지만

하나의 DB에 여러 컨텍스트를 사용하는 것도 가능합니다.

 

여러 컨텍스트를 조인하게 되면 성능이 확 떨어지고 조건에 따라서 마이그레이션 명령이 안 먹힐 수 있습니다.

그래서 하나의 컨텍스트를 사용하는 것을 권장하는 것입니다.

 

이 포스팅에서는 하나의 DB에 여러 컨텍스트를 사용하는 방법에 대해 알아봅시다.

 

 

 

0. 프로젝트 생성 및 기본 세팅

이 포스팅에서는 'SQLite'를 사용할 예정입니다.

(다른 DBMS도 동일합니다.)

 

프로젝트를 생성하고 누겟(Nuget)에서 다음 종속성을 찾아 추가합니다.

- Microsoft.EntityFrameworkCore

- Microsoft.EntityFrameworkCore.Sqlite

- Microsoft.EntityFrameworkCore.Tools

 

 

'Global' 폴더를 만들고 'GlobalStatic.cs'를 추가합니다.

내용은 아래와 같습니다.

namespace EfMultipleContext.Global;

/// <summary>
/// 이 프로젝트에서 사용할 전역 변수
/// </summary>
public static class GlobalStatic
{
	/// <summary>
	/// DB 타입
	/// </summary>
	/// <remarks>저장전에 소문자로 변환해야 한다.</remarks>
	public static string DBType = "sqlite";
	/// <summary>
	/// DB 컨낵션 스트링 저장
	/// </summary>
	public static string DBString = "Data Source=Test.db";
}

 

 

1. 모델 생성

각각의 컨텍스트에 사용할 모델을 만듭니다.

 

'ModelsDB' 폴더를 만들어줍니다.

 

1-1. 학생 모델 만들기

'StudentModel.cs'를 생성하고 아래와 같이 넣어줍니다.

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace ModelsDB;

public class StudentModel
{
	[Key]
	[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
	public int ID { get; set; }
	public string LastName { get; set; } = string.Empty;
	public string FirstMidName { get; set; } = string.Empty;
	public DateTime EnrollmentDate { get; set; }
}

 

1-2. 선생 모델 만들기

'TeacherModel.cs'를 생성하고 아래와 같이 넣어줍니다.

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace ModelsDB;

public class TeacherModel
{
	[Key]
	[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
	public int ID { get; set; }
	public string LastName { get; set; } = string.Empty;
	public string FirstMidName { get; set; } = string.Empty;
	public DateTime HireDate { get; set; }
}

 

 

2. 컨텍스트(Context) 만들기

이제 위에서 만들 모델을 사용하는 각각의 DB컨텍스트(DbContext)를 만들어 줍니다.

 

2-1. 학생 컨텍스트 만들기

'StudentContext.cs'를 생성하고 아래 코드를 넣어줍니다.

using EfMultipleContext.Global;
using Microsoft.EntityFrameworkCore;

namespace ModelsDB;

public class StudentContext : DbContext
{
#pragma warning disable CS8618
	public virtual DbSet<StudentModel> Students { get; set; }
#pragma warning restore CS8618

	protected override void OnConfiguring(DbContextOptionsBuilder options)
	{
		options.UseSqlite(GlobalStatic.DBString);
	}
}

 

2-2. 선생 컨텍스트 만들기

'TeacherContext.cs'를 생성하고 아래 코드를 넣어줍니다.

using EfMultipleContext.Global;
using Microsoft.EntityFrameworkCore;

namespace ModelsDB;

public class TeacherContext : DbContext
{
#pragma warning disable CS8618
	public virtual DbSet<TeacherModel> Teachers { get; set; }
#pragma warning restore CS8618

	protected override void OnConfiguring(DbContextOptionsBuilder options)
	{
		options.UseSqlite(GlobalStatic.DBString);
	}
}

 

 

3. 마이그레이션(Migration) 생성

컨텍스트가 두 개이므로 마이그래이션도 각각 관리해야 합니다.

 

'패키지 관리자 콘솔(package manager console, PM)'에 

마이그레이션 생성 명령어인 'Add-Migration'에 옵션을 설정하여

각각의 폴더를 지정한 후

마이그레이션이 생성될 수 있게 합니다.

 

3-1. 학생 마이그레이션 생성

아래 명령을 이용하여 학생 컨텍스트용 마이그레이션을 생성합니다.

Add-Migration InitialCreate -Context ModelsDB.StudentContext -OutputDir Migrations\StudentMigrations

 

3-2. 선생 마이그레이션 생성

아래 명령을 이용하여 선생 컨텍스트용 마이그레이션을 생성합니다.

Add-Migration InitialCreate -Context ModelsDB.TeacherContext -OutputDir Migrations\TeacherMigrations

 

확인

두 마이그레이션이 생성되었으면 아래와 같은 구조가 됩니다.

 

 

4. 테스트

이제 마이그레이션 내용을 DB에 적용하고 데이터를 넣어봅시다.

 

4-1. 마이그레이션 적용

마이그레이션은 'EF Tool'을 이용해서 명령어로 업데이트할 수 있지만

여기서는 코드에서 진행합니다.

 

아래 코드를 이용해 마이그레이션을 적용할 수 있습니다.

(한번은 실행해야 함)

//학생 마이그레이션 적용
using (StudentContext db1 = new StudentContext())
{
    db1.Database.Migrate();
}

//선생 마이그레이션 적용
using (TeacherContext db2 = new TeacherContext())
{
    db2.Database.Migrate();
}

 

마이그레이션이 적용되었으면 아래와 같이 테이블이 각각 생성된 것을 확인할 수 있습니다.

 

4-2. 데이터 넣기

이제 우리가 일상적으로 'EF'를 사용하는 것처럼 데이터를 넣어 봅시다.

//테스트 데이터 넣기
using (StudentContext db1 = new StudentContext())
{
    db1.Students.Add(
        new StudentModel()
        {
            LastName = "s1",
            FirstMidName = "s2",
            EnrollmentDate = DateTime.Now,
        });
    db1.SaveChanges();
}

using (TeacherContext db2 = new TeacherContext())
{
    db2.Database.Migrate();

    db2.Teachers.Add(
        new TeacherModel()
        {
            LastName = "t1",
            FirstMidName = "t2",
            HireDate = DateTime.Now,
        });
    db2.SaveChanges();
}

 

실행 후 DB를 확인해 보면

데이터가 잘 들어갔음을 알 수 있습니다.

 

 

마무리

테스트 프로젝트 : github - dang-gun/DotNetSamples/EfMultipleContext/

참고 : MS Learn - 여러 공급자를 사용하여 마이그레이션

 

EF가 업데이트되면서 예전에 쓰던 명령어가 사라지는 바람에.....

검색자료가 뒤죽박죽이라 겨우 찾았네요;;;

 

여기서 조심해야 할 것이 상황에 따라서 몇몇 마이그레이션 명령이 먹히지 않는 경우가 있습니다.

그래서 가급적 한 개의 DB에는 한 개의 마이그레이션만 사용하는 것이 좋은 것이죠.