이번에 .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개의 좋아요
UserAuthority enum 관련 Configuration 아무것도 필요 없습니다. 싹다 지워도 됩니다.
IsRequired는 nullable 여부를 설정하는 옵션이에요.