entityframework migration 관련 질문

이번에 .net8과 ef8을 공부하는 중에 도저히 이유를 알 수 없는 오류에 맞닥뜨리게 되어 질문하게 되었습니다.

public class UserAuthorityEntity{
public int Id{get; set;}
public UserAuthority UserAuthority {get; set;}
public int UserId {get; set;}

    public virtual UserEntity? UserEntity { get; set; }
}

public enum UserAuthority{
General = 1, //일반 사용자
Admin = 2, //관리자
Employee = 3 //직원
}

public class UserAuthorityEntityConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
builder.ToTable(“UserAuthority”);
builder.HasKey(userAuthority => userAuthority.Id);
builder.Property(userAuthority => userAuthority.UserAuthority)
.IsRequired()
. .HasConversion()
.HasDefaultValue((int)UserAuthority.General);
builder.HasOne(userAuthority => userAuthority.UserEntity)
.WithMany(user => user.UserAuthorities)
.HasForeignKey(userAuthority => userAuthority.UserId)
.OnDelete(DeleteBehavior.Cascade);
}
}

이렇게 구성하여 마이그레이션을 진행하였는데

Unable to create a ‘DbContext’ of type ‘’. The exception ‘Cannot set default value ‘1’ of type ‘System.Int32’ on property ‘UserAuthority’ of type ‘wms_api.Models.Enums.UserAuthority’ in entity type ‘UserAuthorityEntity’.’ was
thrown while attempting to create an instance. For the different patterns supported at design time, see Design-time DbContext Creation - EF Core | Microsoft Learn
해당 오류가 발생합니다.
HasConversion로 int형으로 변환해서 문제가 없을거라 생각했는데 문제가 발생하여 이곳저곳에서 검색해보아도 도저히 답을 모르겠어서 여기에 질문드리게 되었습니다.

우선, fluent configuration에서, 형식 파라미터가 빠져있네요.

public class UserAuthorityEntityConfiguration
    : IEntityTypeConfiguration<UserAuthorityEntity>

문제가 되는 곳은

public void Configure(EntityTypeBuilder builder)
{
   // ...

   builder.Property(userAuthority => userAuthority.UserAuthority)
      .IsRequired()
     .HasConversion() // 삭제
     .HasDefaultValue((int)UserAuthority.General);

 // ...

"삭제"라고 표시된 부분을 삭제하거나, .HasConversion<int>() 처럼 변환 형식을 지정해 보세요.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using wms_api.Models.Enums;

public class UserAuthorityEntityConfiguration : IEntityTypeConfiguration<UserAuthorityEntity>
{
    public void Configure(EntityTypeBuilder<UserAuthorityEntity> builder)
    {
        builder.ToTable("UserAuthority");
        builder.HasKey(userAuthority => userAuthority.Id);
        builder.Property(userAuthority => userAuthority.UserAuthority)
            .IsRequired()
            .HasConversion<int>()
            .HasDefaultValue((int)UserAuthority.General);
            // .HasDefaultValueSql("1");
        builder.HasOne(userAuthority => userAuthority.UserEntity)
            .WithMany(user => user.UserAuthorities)
            .HasForeignKey(userAuthority => userAuthority.UserId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

이렇게 까지 했었었는데 똑같이 오류가 발생합니다. 왜그런지 모르겠네요

아래와 같이 변경하거나,

.HasDefaultValue(UserAuthority.General);

이 부분을 삭제하고

        builder.ToTable("UserAuthority");
        builder.HasKey(userAuthority => userAuthority.Id);
        builder.Property(userAuthority => userAuthority.UserAuthority)
            .IsRequired()
            .HasConversion<int>()
            .HasDefaultValue((int)UserAuthority.General);
            // .HasDefaultValueSql("1");

엔티티 클래스를 아래와 같이 변경하면, 컨벤션이 알아서 처리해줍니다.

public class UserAuthorityEntity
{
   // ...
   public UserAuthority UserAuthority {get; set;} =  UserAuthority.General;
   // ...
}

모델 Configuration 은 컨벤션을 숙지하고 나서, 컨벤션을 따르지 않는 경우에만 적용하는 게 좋습니다.

        builder.ToTable("user_authorities");
      
        builder.Property(userAuthority => userAuthority.UserAuthority)
            .HasConversion(
               // instance type to DB compatible CLR type
               obj => obj.ToString(), 
               // DB compatible CLR type to instance type
               str => Enum.Parse(typeof(UserAuthority), str)  
            )
            ;
3 Likes

UserAuthority enum 관련 Configuration 아무것도 필요 없습니다. 싹다 지워도 됩니다.

IsRequired는 nullable 여부를 설정하는 옵션이에요.