Миграции EF Core не принимают значения заполняющих данных

У меня проблема с EF Core Migrations в DataSeeding. У меня есть следующая конфигурация сущности:

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 с созданием таблицы все в порядке, но вставка данных очень корявая:

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. Я делаю некоторые настройки неправильно, или это ожидаемое поведение?

С наилучшими пожеланиями,

Джулиан


person Julian    schedule 22.01.2021    source источник


Ответы (1)


После долгих поисков я нашел почему так происходит и решение.

Вот ссылка на решение:

Параметры Шаблоны, которые делают это лучше, используя в качестве примера логическое значение по умолчанию true.

A: Используйте значения по умолчанию на стороне клиента.

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

а также

.HasDefaultValue(true)
.ValueGeneratedNever();

(Если мы введем режим скаффолдинга, который не включает все артефакты базы данных, мы можем пропустить это.)

При написании кода вручную мы бы рекомендовали только:

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

и никакой конфигурации, созданной в магазине, если только вам не нужны миграции для создания конфигурации по умолчанию в базе данных.

B: Используйте обычные свойства, поддерживаемые полем, допускающим значение NULL. Этот подход сохранит все поведение, создаваемое хранилищем, за счет большего количества кода. Кроме того, нам нужно внести изменения в EF, чтобы это заработало, но они не должны быть сложными.

Код одинаков как для скаффолдинга, так и для написания вручную:

public class Blog
{
    private bool? _isValid;

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

а также

    .HasDefaultValue(true);

(Не должно быть необходимости устанавливать режим доступа к свойству, так как мы читаем/записываем поля по умолчанию в 3.0.)

C: Использовать свойства, допускающие значение NULL Это сохраняет поведение, создаваемое хранилищем, но заставляет тип в модели допускать значение NULL.

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

а также

    .HasDefaultValue(true);
person Julian    schedule 25.01.2021