EF Core 11 Complex Types·FullJoin 프리뷰를 도입하기 전 검증 항목
ORM의 새 기능은 샘플 코드에서는 쉽게 동작하지만, 실제 서비스에서는 모델·데이터베이스·마이그레이션·쿼리 번역이 함께 움직여야 합니다. 특히 EF Core 11처럼 개발 중인 버전은 기능 목록보다 호환성 확인이 먼저입니다.
이번 글에서는 Complex Types와 FullJoin 같은 기능을 바로 채택하자는 이야기가 아니라, 적용 여부를 판단하기 위해 어떤 실험을 해야 하는지 정리합니다. 테스트 환경과 버전은 글을 읽는 시점에 다시 확인해야 합니다.
기능 이름보다 지원 범위를 고정합니다
새 기능을 읽을 때는 무엇이 가능한지보다 어떤 데이터베이스와 런타임에서 가능한지 먼저 기록합니다. EF Core 11은 .NET 11 SDK와 런타임을 요구하는 개발 중 버전이므로, 기존 서비스가 사용하는 타깃 프레임워크와 분리해 검증해야 합니다.
문서의 예제가 모든 공급자에서 동일하게 동작한다고 가정하지 않습니다. SQL Server·SQLite·Cosmos처럼 공급자가 다르면 번역과 마이그레이션 결과도 달라질 수 있습니다.
- 런타임: SDK와 애플리케이션 런타임 버전을 기록합니다.
- 공급자: 실제 운영 데이터베이스와 테스트 공급자를 맞춥니다.
- 기능 상태: 개발 중·실험적·안정적 상태를 구분합니다.
Complex Types는 모델 경계를 먼저 확인합니다
Complex Types는 엔터티의 식별성을 갖지 않는 값 묶음을 표현하는 데 유용할 수 있습니다. 하지만 기존에 별도 엔터티로 저장하던 구조를 바꾸면 변경 추적과 마이그레이션이 달라질 수 있습니다.
저는 주소나 설정 값처럼 생명주기가 부모와 같은 데이터부터 실험합니다. 별도 조회와 권한이 필요한 데이터를 무리하게 합치지 않고, 저장·수정·검색의 사용 패턴을 먼저 확인합니다.
질문확인할 것위험 신호
| 식별성이 필요한가 | 독립 조회·권한·이력 | 부모에 종속되지 않는 데이터 |
| 변경 추적이 단순한가 | 부분 수정·동시성 | 의도치 않은 전체 갱신 |
| 쿼리가 번역되는가 | 실제 SQL과 인덱스 | 메모리에서 추가 필터링 |
FullJoin은 결과 의미와 데이터 중복을 시험합니다
FullJoin은 양쪽 데이터의 일치·불일치 행을 함께 보고 싶을 때 유용할 수 있습니다. 그러나 결과에 양쪽 키가 비어 있는 경우를 어떻게 표현할지, 중복이 있을 때 행이 몇 개 생기는지 먼저 정해야 합니다.
샘플 두 행으로는 문제가 보이지 않습니다. 실제 운영 데이터와 비슷한 중복·누락·빈 값·큰 범위를 넣고 생성된 SQL과 실행 계획을 확인해야 합니다.
- 일치 행: 양쪽 값이 결합될 때 우선순위를 정합니다.
- 왼쪽만 존재: 오른쪽 값이 없을 때 DTO의 기본값을 정의합니다.
- 오른쪽만 존재: 후속 처리에서 누락으로 오해하지 않도록 표시합니다.
- 중복: 키가 유일하지 않을 때 결과 행 수를 검증합니다.
프리뷰 도입은 회귀 테스트와 롤백으로 끝납니다
기능이 동작한다는 확인만으로는 부족합니다. 기존 쿼리 결과와 새 쿼리 결과가 같은 입력에서 일치하는지, 마이그레이션을 되돌릴 수 있는지, 운영 로그가 해석되는지 확인해야 합니다.
프리뷰 기능을 한 번에 여러 곳에 넣지 않고 한 저장소나 읽기 전용 경로에서 시작하면 문제가 생겨도 영향 범위를 줄일 수 있습니다. 정식 버전이 나오면 같은 체크리스트를 다시 실행합니다.
실험 결과를 운영 판단으로 바꾸는 순서
개발 문서에서 가장 재사용하기 어려운 문장은 ‘잘 됩니다’입니다. 어떤 버전과 데이터, 부하에서 잘 되었는지 모르면 독자는 자신의 환경에서 다시 확인할 수 없습니다. 저는 새로운 기능을 검토할 때 SDK·런타임·패키지·데이터베이스 버전을 먼저 고정하고, 기존 구현을 기준선으로 보관합니다. 변경 전후의 코드와 측정 명령도 함께 기록합니다.
측정값이 좋아도 운영에 바로 도입하지 않습니다. 오류 추적, 로그의 의미, 배포와 롤백, 팀이 이해할 수 있는지까지 확인합니다. 프리뷰나 변경 중인 문서는 정식 기능과 구분하고, 문서에 확인 날짜와 테스트 범위를 적습니다. 독자가 복사해 사용해도 위험하지 않도록 적용하지 말아야 하는 조건도 함께 적는 것이 기술 글의 중요한 부분입니다.
- 버전 잠금: 실험한 SDK·런타임·패키지·브라우저 버전을 기록합니다.
- 기준선: 변경 전 기능·성능·오류 결과를 같은 입력으로 보관합니다.
- 경계 사례: 빈 값·중복·실패·큰 입력에서 결과를 확인합니다.
- 배포 판단: 적용·보류·롤백 중 하나를 고르고 근거를 남깁니다.
다음 작업에서 다시 확인할 항목
한 번 적용한 방법이 언제나 같은 결과를 내는 것은 아닙니다. 사람과 서비스와 원고의 조건이 바뀌면 같은 원칙도 다른 판단을 요구합니다. 그래서 저는 글을 작성한 뒤 결론만 보관하지 않고, 결론이 성립한 조건과 다시 확인해야 할 조건을 함께 적습니다. 이 기록이 있으면 몇 달 뒤 글을 업데이트할 때 당시의 경험을 현재의 사실처럼 착각하지 않을 수 있습니다.
특히 버전·정책·가격·플랫폼 기능처럼 외부에서 바뀌는 내용은 조사한 날짜와 공식 문서의 주소를 남깁니다. 발행 시점에 문서가 달라졌다면 본문에 변경 사실을 표시하고, 직접 확인하지 못한 부분은 독자가 알 수 있도록 범위를 제한합니다. 경험을 공유하는 글도 다른 사람의 환경에 그대로 적용될 수 있으므로, 성공 사례보다 실패 조건을 함께 쓰는 편이 안전합니다.
마지막으로 이 글을 읽은 분이 바로 할 수 있는 행동은 하나로 줄입니다. 모든 항목을 한꺼번에 바꾸기보다 현재 상태를 기록하고, 작은 실험을 한 번 실행하고, 결과를 다시 적는 순서입니다. 그렇게 쌓인 기록이 다음 글의 소재가 되고, 처음의 판단을 더 정확하게 고쳐 쓰는 근거가 됩니다.
- 범위 표시: 이 글의 결론이 적용되는 환경과 적용되지 않는 환경을 구분합니다.
- 날짜 기록: 버전·정책·가격·문서를 확인한 날짜를 남깁니다.
- 실패 조건: 어떤 상황에서는 이 방법을 쓰지 말아야 하는지 적습니다.
- 작은 실행: 독자가 오늘 시도할 수 있는 가장 작은 행동을 고릅니다.
- 후속 기록: 실행 결과와 다음에 바꿀 조건을 별도 메모로 남깁니다.
이 기록을 나중에 다시 읽을 때는 결과만 보지 않고 당시의 조건도 함께 확인합니다. 조건이 달라졌다면 결론을 그대로 복사하지 말고 현재의 입력과 제약을 다시 적습니다. 그 과정을 거쳐야 이 글이 단순한 경험담이 아니라 다음 판단을 돕는 작업 기록으로 남습니다.
마치며
EF Core 11의 새 기능은 기능 목록만 읽고 도입할 주제가 아니라, 실제 모델·쿼리·공급자·롤백을 함께 확인해야 하는 실험 주제입니다. 관심 있는 기능 하나를 골라 운영 데이터와 비슷한 경계 사례부터 테스트해 보시기 바랍니다.
참고한 문서: EF Core 11 공식 문서 · .NET 11 공식 문서