Entity Framework 계층 구조 당 테이블
Entity Framework에서 상속 유형은 무엇입니까?
Entity Framework 코드는 먼저 각 구체적인 도메인 클래스에 대한 테이블을 만듭니다. 상속을 사용하여 도메인 클래스를 디자인 할 수도 있습니다.
- 객체 지향 프로그래밍에서는 "has a" 와 "is a" 관계를 포함 할 수 있지만 SQL 기반 관계형 모델에서는 테이블간에 "has a" 관계 만 있고 유형 상속은 지원되지 않습니다.
- 그렇다면, 어떻게 객체 지향 도메인 클래스를 관계형 데이터베이스와 매핑 할 수 있을까요?
대답
Entity Framework에서 상속 계층 구조를 나타내는 세 가지 방법이 있습니다.
계층 구조 당 테이블 (TPH)
TPH 상속은 하나의 데이터베이스 테이블을 사용하여 상속 계층 구조의 모든 엔터티 형식에 대한 데이터를 유지 관리합니다.
- 전체 클래스 계층 구조는 단일 테이블로 매핑 될 수 있습니다.
- 이 테이블에는 계층 구조의 모든 클래스에 대한 모든 속성에 대한 열이 포함됩니다.
- 특정의 행에 의해 나타내지는 구상 서브 클래스는 타입 판별 자의 값에 의해 식별됩니다.
코드 우선의 TPH
TPH를 사용하려면 코드 우선에서 특별한 작업을 수행 할 필요가 없습니다. 이것은 기본 상속 매핑 전략입니다. 다음은 하나의 추상 클래스 Person
과 두 개의 비 추상적 클래스 Student
와 Teacher
를 포함하는 매우 간단한 모델입니다. Student
클래스와 Teacher
클래스는 Person 클래스를 상속합니다.
public abstract class Person
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class Student : Person
{
public DateTime EnrollmentDate { get; set; }
}
public class Teacher : Person
{
public DateTime HireDate { get; set; }
}
public class EntityContext : DbContext
{
public DbSet<Person> People { get; set; }
}
새로운 레코드를 데이터베이스에 추가해 보겠습니다.
using (var context = new EntityContext())
{
Student student = new Student()
{
FullName = "Mark",
EnrollmentDate = DateTime.Now
};
Teacher teacher = new Teacher()
{
FullName = "John",
HireDate = DateTime.Now
};
context.People.Add(student);
context.People.Add(teacher);
context.SaveChanges();
}
DB 스키마에서 볼 수 있듯이 Code First는 모든 속성을 하나의 테이블에 추가했으며 영구 클래스를 구별 할 수 있도록 식별자 (discriminator) 열을 추가했습니다.

TPH에는 한 가지 주요한 문제가 있습니다. 하위 클래스가 선언 한 속성의 열은 데이터베이스에서 Nullable입니다.
- 예를 들어, Code First는 Teacher 클래스의 HireDate 속성과 Student 클래스의 EnrollmentDate를 매핑하기 위해 (DATETIME, NULL) 열을 만들었습니다.
- 교사용 인스턴스에는 EnrollmentDate 속성이 없습니다. 해당 행에 대해 EnrollmentDate 필드가 NULL이어야합니다.
- 마찬가지로 학생 인스턴스는 HiretDate 속성을 가지지 않으므로 HiretDate 필드는 해당 행에 대해 NULL이어야합니다.
생성 된 SQL보기
모든 학생과 교사의 목록을 반환하는 SQL 쿼리를 살펴 보겠습니다.
var query = context.People.ToString();
이 쿼리는 데이터베이스에서 실행 된 다음 SQL 문을 생성했습니다.
SELECT
[Extent1].[Discriminator] AS [Discriminator],
[Extent1].[Id] AS [Id],
[Extent1].[FullName] AS [FullName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate],
[Extent1].[HireDate] AS [HireDate]
FROM [dbo].[People] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'Student',N'Teacher')