EF Core 迁移不采用种子数据值

EF Core Migrations do not take seeding data values

我在 DataSeeding 中遇到 EF Core 迁移问题。我有以下实体配置:

public void Configure(EntityTypeBuilder<ChartOptionsModel> builder)
        {
            builder.ToTable("charts_options");

            //Columns description
            builder.Property(s => s.Id)
                .UseIdentityColumn()
                .HasColumnName("id")
                .HasColumnType("bigint");

            builder.Property(s => s.GroupId)
                .HasColumnName("group_id")
                .HasColumnType("bigint")
                .HasDefaultValue(1);

            builder.Property(s => s.Type)
                .HasColumnName("type")
                .HasColumnType("varchar(50)")
                .HasDefaultValue("");

            builder.Property(s => s.Title)
                .HasColumnName("title")
                .HasColumnType("text")
                .HasDefaultValue("");

            builder.Property(s => s.LabelFormatter)
                .HasColumnName("label_formatter")
                .HasColumnType("text")
                .HasDefaultValue("");

            builder.Property(s => s.ShowChart)
                .HasColumnName("show_chart")
                .HasColumnType("boolean")
                .HasDefaultValue(true);

            //Keys
            builder.HasKey(s => s.Id)
                .HasName("charts_options_pkey");

            //FK
            builder.HasOne(s => s.Group)
                .WithMany(s => s.ChartsOptions)
                .HasForeignKey(s => s.GroupId)
                .HasConstraintName("charts_options_group_id_fkey");

            //Indices
            builder.HasIndex(s => s.GroupId)
                .HasDatabaseName("charts_options_group_id_idx");

            builder.HasData(ChartsOptionsSeedingData.ChartsOptions);
        }

当我使用 Add-Migration [Migration name] 创建迁移时,我在迁移的 BuildTargetModel 方法中得到了这个:

modelBuilder.Entity("DatabaseManagerService.Database.Models.Charts.ChartOptionsModel", b =>
 {
     
     //other fields

     b.Property<bool>("ShowChart")
         .ValueGeneratedOnAdd()
         .HasColumnType("boolean")
         .HasDefaultValue(true)
         .HasColumnName("show_chart");

     b.Property<string>("Title")
         .ValueGeneratedOnAdd()
         .HasColumnType("text")
         .HasDefaultValue("")
         .HasColumnName("title");

     b.Property<string>("Type")
         .ValueGeneratedOnAdd()
         .HasColumnType("varchar(50)")
         .HasDefaultValue("")
         .HasColumnName("type");

     //other fields

     b.ToTable("charts_options");

     b.HasData(
         new
         {
             Id = 1L,
             GroupId = 1L,
             LabelFormatter = "`${vals[0]} of ${vals[0] + vals[1]}`",
             ShowChart = false,
             Title = "AHU In Local",
             Type = "AHUInLocalChart"
         },
         new
         {
             Id = 2L,
             GroupId = 1L,
             LabelFormatter = "`${vals[0]} of ${vals[0] + vals[1]}`",
             ShowChart = false,
             Title = "FQC In Local",
             Type = "FQCInLocalChart"
         },
    
    // other values here
    
         );
 });

Up方法中table创建是可以的,但是数据的插入很麻烦:

migrationBuilder.InsertData(
table: "charts_options",
columns: new[] { "id", "group_id", "label_formatter", "title", "type" },
values: new object[,]
{
    { 1L, 1L, "`${vals[0]} of ${vals[0] + vals[1]}`", "AHU In Local", "AHUInLocalChart" },
    { 21L, 3L, "`${vals[0]} of ${vals[0] + vals[1]}`", "HТ OK", "HTOkChart" },
    //rest of the values
});

问题是,尽管 ShowChart 属性 的默认值是 true,并且在模型快照中我的前两行有 ShowChart = false数据,生成的 insert 语句,没有列 show_chart,对应的值 - false。 我是不是做错了一些配置,或者这是预期的行为?

此致,

朱利安

经过长时间的搜索,我找到了发生这种情况的原因和解决方案。

Here是link的解法:

选项 使这更好的模式,例如使用默认为 true 的 bool。

A:使用客户端默认值 我们将脚手架:

public class Blog
{
    public bool IsValid { get; set; } = true;
}

.HasDefaultValue(true)
.ValueGeneratedNever();

(如果我们引入不包括所有数据库工件的脚手架模式,那么我们可以跳过这个。)

手动编写代码时,我们建议:

public class Blog
{
    public bool IsValid { get; set; } = true;
}

除非您需要迁移以在数据库中创建默认值,否则没有存储生成的配置。

B:使用可空字段支持的常规属性 这种方法将以更多代码为代价保留所有存储生成的行为。此外,我们需要对 EF 进行更改才能使其正常工作,但它们不应太复杂。

脚手架和手写的代码是一样的:

public class Blog
{
    private bool? _isValid;

    public bool IsValid
    {
        get => _isValid ?? false;
        set => _isValid = value;
    }
}

    .HasDefaultValue(true);

(应该不需要设置属性访问模式,因为我们在3.0中默认[=​​46=]字段。)

C:使用可为空的属性 这保留了存储生成的行为,但强制模型中的类型可为空。

public class Blog
{
    public bool? IsValid { get; set; };
}

    .HasDefaultValue(true);