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 ๋””์ž์ธ ํƒ€์ž„ DbContext ๋งŒ๋“ค๊ธฐ - 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 ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์ด์—์š”.