일대다 관계 설정하기
Casecade Delete를 이해하기에 앞서, Entity를 일대다로 연관관계를 맺는방법을 알아야합니다.
순수하게 Db설계에서는 단순하게 자식테이블의 특정 id가 부모의 외래키가 설정된 케이스입니다.
어노테이션 VS Flent API : 혼합및 양자택일가능합니다.
어노테이션으로 설정 | Fluent API사용하여 설정 |
---|---|
[Table("tokenhistory")] public class TokenHistory { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int TokenHistoryId { get; set; } [ForeignKey("UserForeignKey")] public User User { get; set; } } [Table("user")] public class User { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public List<TokenHistory> TokenHistorys { get; set; } } | public class AccountContent : DbContext { public DbSet<User> Users { get; set; } public DbSet<TokenHistory> TokenHistories { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { //관계설정 modelBuilder.Entity<TokenHistory>() .HasOne(t => t.User) .WithMany(b => b.TokenHistorys); } } |
일대다 관계형성을 위한 외래키설정은 어노테이션만으로도 할수 있으며, 객 체의 순수성을 보장하기위해 ( 객체에는 객체만 정의)
FluentAPI를 통해 설정도 가능합니다. 각각은 장단점이 있음으로 일괄적인 방식을 위해 어느 한가지 방식을 선택하면 되겠습니다.
특수한 DDL의 경우 어노테이션이 지원하지 않는 케이스도 있기때문에, 마이그레이션을 포함하여 DDL까지 모두 커버하려면
FluentAPI 를 사용한 일괄적 방법이 권장됩니다.
하위항목 삭제
일대다(부모 vs 자식) 관계에서 부모만 삭제한다고 가정해봅시다. DBMS에서는
다음과 같은전략 3가지중 하나를 선택할수가 있습니다.
- 자식/종속을 삭제할 수 있습니다.
- 자식의 외래 키 값을 null로 설정할 수 있습니다.
- 자식을 변경하지 않고 그대로 유지합니다.
하지만 DBMS마다 위 트리거를 이용하는 방법은 각각 다를것이며, 고아(부로를 잃는)를 방지하기 위한
제약조건을 거는 방법도 각각 다를것입니다.
FluentAPI설정의 OnDelete 설정을 통해,
public class AccountContent : DbContext { public DbSet<User> Users { get; set; } public DbSet<TokenHistory> TokenHistories { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { //관계설정및 삭제전략 modelBuilder.Entity<TokenHistory>() .HasOne(t => t.User) .WithMany(b => b.TokenHistorys) .OnDelete(DeleteBehavior.Cascade); //인덱스 설정 modelBuilder.Entity<TokenHistory>() .HasIndex(t => new { t.AuthToken }) .IsUnique(true); } }
- ClientSetNull : 메모리 객체에서만 Null이됩니다.
- Restrict : 그냥 방치합니다. ( 고아가 생김)
- SetNull : 외래키를 Null로 셋팅하여 참조관계를 끊어주기만 합니다. 이후에 일괄적인 정리가 가능합니다.
- Cascade : 자식 객체를 모두 제거합니다.
MSDN 공식문서 :https://docs.microsoft.com/ko-kr/ef/core/saving/cascade-delete