[Entity Framework 6] 하나의 DB에 여러 컨텍스트(Multiple DbContext) 사용하기
프로젝트를 진행하다 보면 여러 가지 이유로 컨텍스트(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/EntityFrameworkSample/MultipleContext/
참고 : MS Learn - 여러 공급자를 사용하여 마이그레이션
EF가 업데이트되면서 예전에 쓰던 명령어가 사라지는 바람에.....
검색자료가 뒤죽박죽이라 겨우 찾았네요;;;
여기서 조심해야 할 것이 상황에 따라서 몇몇 마이그레이션 명령이 먹히지 않는 경우가 있습니다.
그래서 가급적 한 개의 DB에는 한 개의 마이그레이션만 사용하는 것이 좋은 것이죠.