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);
我在 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);