이전 포스팅에서는 하나의 DB에 여러 컨텍스트를 사용하기 위해 각각 마이그레이션을 생성해서 관리하는 방법을 사용했습니다.
이 방법은 여러 개의 마이그레이션을 관리해야 해서 불편함이 많습니다.
그래서 전체를 관리하는 컨텍스트를 만들고 마이그레이션과 조인이 필요할 때는 이 '전체 컨텍스트'를 따로 만들어 사용하는 것이 좋습니다.
이 방법의 단점은 전체용 컨텍스트를 따로 관리해야 한다는 것인데.....
관리와 성능의 이점을 생각하면 이 정도는 단점이라고 할수 없죠 ㅎㅎㅎㅎ
결국 마이그레이션만 따로 관리할 뿐 컨택스트를 하나만 쓰는 것과 다름없는 구조가 됩니다.
이전 포스팅에서
(참고 : [Entity Framework 6] 하나의 DB에 여러 컨텍스트(Multiple DbContext) 사용하기 )
0. 프로젝트 생성 및 기본 세팅
1. 모델 생성
2. 컨텍스트(Context) 만들기
까지 따라 합니다.
'ModelsDB'폴더에 'AllContext' 클래스를 생성합니다.
이 컨텍스트에는 관리할 모든 테이블의 'DbSet'을 넣어줍니다.
using EfMultipleContext2.Global; using Microsoft.EntityFrameworkCore; namespace ModelsDB; public class AllContext : DbContext { #pragma warning disable CS8618 public virtual DbSet<StudentModel> Students { get; set; } public virtual DbSet<TeacherModel> Teachers { get; set; } #pragma warning restore CS8618 protected override void OnConfiguring(DbContextOptionsBuilder options) { options.UseSqlite(GlobalStatic.DBString); } }
마이그레이션 생성은 'AllContext'만 하면 됩니다.
Add-Migration InitialCreate -Context ModelsDB.AllContext -OutputDir Migrations\AllMigrations
이제 아래 코드를 넣어두면 전체 마이그레이션이 됩니다.
(직접 EF명령어를 날려 마이그레이션 해도 됩니다.)
//전체 첫 마이그레이션 생성 //Add-Migration InitialCreate -Context ModelsDB.AllContext -OutputDir Migrations\AllMigrations using (AllContext dbAll = new AllContext()) { dbAll.Database.Migrate(); }
테스트용으로 'Students'와 'Teachers'를 조인해 봅시다.
using (AllContext dbAll = new AllContext()) { var all = (from s in dbAll.Students join t in dbAll.Teachers on s.ID equals t.ID select new { t, s }) .ToList(); Console.WriteLine(all); }
조인도 잘되네요.
EF에서는 한 쿼리문에서 여러 컨택스트를 사용하는 걸 허용하지 않습니다.
그러므로 한쪽 컨택스트의 쿼리결과를 미리 받아야 합니다.
아래 코드를 넣고 돌려봅시다.
using (StudentContext db_1 = new StudentContext()) { using (TeacherContext db_2 = new TeacherContext()) { var all = (from s in db_1.Students join t in db_2.Teachers on s.ID equals t.ID select new { t, s }) .ToList(); Console.WriteLine(all); } }
다음과 같은 에러가 납니다.
System.InvalidOperationException: 'Cannot use multiple context instances within a single query execution. Ensure the query uses a single context instance.'
단일 쿼리 실행 내에서 여러 컨텍스트 인스턴스를 사용할 수 없습니다. 쿼리가 단일 컨텍스트 인스턴스를 사용하는지 확인하십시오.
방법이야 미리 리스트를 받아오는 방법뿐이 없습니다.
아래 코드는 '.ToList()'를 통해서 데이터를 미리 받아오고 있습니다.
using (StudentContext db_1 = new StudentContext()) { using (TeacherContext db_2 = new TeacherContext()) { List<StudentModel> listStu = db_1.Students.ToList(); var all = (from s in listStu join t in db_2.Teachers on s.ID equals t.ID select new { t, s }) .ToList(); Console.WriteLine(all); } }
일반적으로 컨텍스트 하나로 조인하는 게 두 개로 조인하는 것보다 빠른데.....
상황에 따라서는 아닐 수도 있습니다.
(이 프로젝트도 컨텍스트 두 개 쓰는게 조금 더 빠릅니다 ㅎㅎㅎ)
테스트 프로젝트 : github - dang-gun/EntityFrameworkSample/MultipleContext2/
참고 : stackoverflow - An error occurred while accessing the Microsoft.Extensions.Hosting services when do first migrations - Shervin Ivari님 답변
이전 포스팅에 붙이기에는 주제가 안 맞고
따로 포스팅하자니 내용이 이전 포스팅과 겹치고....