공부/EFCore
[EFCore] 다수의 Navigational Property가 같은 클래스를 참조하는 상황, 어떻게 대처할까
돌멩이수프
2022. 9. 7. 15:39
728x90
public class Item
{
// ... //
public Player Owner { get; set; }
public Player Creator { get; set; }
}
아이템을 생성한 Player와 아이템을 소유하고 있는 Player를 모두 나타내고 싶을 때는 어떤 방법을 사용해야 할까? 기존에 사용하던 Convention 방식을 사용하면 에러가 발생한다. (OwnerId와 CreatorId 두 개를 추가해주는 방식)
✅ 이때 우리가 사용할 수 있는 게 DataAnnotation 방식이다.
public class Item
{
// ... //
public int? OwnerId { get; set; }
[InverseProperty("OwnedItem")]
public Player Owner { get; set; }
public int? CreatorId { get; set; }
[InverseProperty("CreatedItems")]
public Player Creator { get; set; }
}
public class Player
{
// ... //
public Item OwnedItem { get; set; }
public ICollection<Item> CreatedItems { get; set; }
}
각각 물고 있고 싶은 프로퍼티를 물고 있으면 된다. Player에 있는 OwnedItem이 [InverseProperty("Owner")]를 물고 있어도 정상 작동한다.
✅ Fluent API로 만드는 방법도 있다.
기존에 만든 DataAnnotation 방식의 주석은 모두 삭제하고,
protected override void OnModelCreating(ModelBuilder builder)
{
// ... //
builder.Entity<Player>()
.HasMany(p => p.CreatedItems)
.WithOne(i => i.Creator) // 상대쪽
.HasForeignKey(i => i.CreatorId);
builder.Entity<Player>()
.HasOne(p => p.OwnedItem)
.WithOne(i => i.Owner)
.HasForeignKey<Item>(i => i.OwnerId);
}
AppDbContext에 내용을 추가해준다. 자신과 상대를 연결한뒤 FK로 설정하고 싶은 프로퍼티를 작성하면 다수의 Navigational Property가 같은 클래스를 참조하는 상황도 잘 대처할 수 있다.
728x90