공부/EFCore

[EFCore] 상속 관계를 매핑해보자 : Table Per Hierarchy (THP) 만들기

돌멩이수프 2022. 9. 8. 11:54
728x90

 

게임 내에 여러 아이템 중 이벤트 기간 동안만 생성됐다가 기간이 끝나면 삭제되는 아이템이 있다. 그런 이벤트아이템은 기존 아이템의 모든 속성을 상속받고 자신의 특징으로는 사라지는 기한만을 설정한다. 이 두 아이템을 다른 테이블로 설정하기 보다는 같은 아이템 테이블에 넣고, 상속 여부만 체크해주는 편이 좋다. 이런 상황에서 THP를 사용하면 된다.

 

 

✅ Convention으로 만들기

 

public class EventItem : Item
{
    public DateTime DestroyDate { get; set; }
}

 

기존 아이템을 만드는 클래스에서 Item을 상속 받는 EventItem 클래스를 만들어준다.

 

new EventItem()
{
    TemplateId = 102,
    CreateDate = DateTime.Now,
    Owner = faker,
    DestroyDate = DateTime.Now,
},

 

기존 아이템을 생성하는 DbCommands -> CreateData 등에서 new EventItem()을 해준다.

 

public DbSet<EventItem> EventItems { get; set; }

 

DbSet으로 EventItem을 추가해준다. 

 

 

따로 설정해준 적 없는 Discriminator가 생기면서 위에서 만든 102번 아이템만 EventItem으로 정상적으로 생성됐다.

Convention의 경우 결국 2가지 DbSet이 생성되어 Item과 EventItem을 따로 관리해야 한다는 불편함이 있다.

 

 

✅ Fluent API로 만들기

 

기존에 만든 DbSet만 삭제하고 Fluent API 방식의 TPH를 만들어보자.

 

public enum ItemType
{
    NormalItem,
    EventItem
}

public class Item
{
    public ItemType Type { get; set; }
    // ... //
 }

 

일반 Item과 EventItem을 구분하기 위해 enum을 생성해준다.

 

builder.Entity<Item>()
    .HasDiscriminator(i => i.Type)
    .HasValue<Item>(ItemType.NormalItem)
    .HasValue<EventItem>(ItemType.EventItem);

 

AppDbContext에 코드를 추가해준다. Item은 NormalItem으로 EventItem은 EventItem으로 자동 설정된다.

 

 

간편하게 Type으로 상속 여부를 확인할 수 있다.

 

728x90