问题描述
这是EF Core 3.1。我有几个带有布尔字段IsActive
的模型,定义如下:
public class Job
{
public bool? IsActive { get; set; }
}
我的种子数据如下:
modelBuilder.Entity<Job>()
.Property(e => e.IsActive)
.HasDefaultValue(true);
modelBuilder.Entity<Job>().HasData(
new Job() { IsActive = true });
每次创建迁移时(包括如果我进行的迁移都没有进行任何更改,这会产生一个空的迁移),它将对上面的字段进行UpdateData
调用,如下所示:
migrationBuilder.UpdateData(
table: "Jobs",keyColumn: "id",keyvalue: 1L,column: "IsActive",value: true);
我还在TodoApi app和setup a GitHub repo中向对更多细节感兴趣的人复制了此行为。
我了解that happening when the seed data is being generated by a function或类似DateTime.Now
之类的结果。我不知道在播种期间为该列分配了原始布尔值时会发生这种情况。
此行为似乎与issue #13047非常相似,“将BoolToStringConverter与HasData一起使用时生成了不正确的UpdateData操作”,但问题为was fixed in EF Core 2.2。
解决方法
原因是下面的模型配置代码中的HasDefaultValue(true)
调用-
modelBuilder.Entity<Job>()
.Property(e => e.IsActive)
.HasDefaultValue(true);
每当您使用HasDefaultValue()
方法为属性设置默认值时,那个就是要为数据库表中相应列设置的值。
使用HasDefaultValue(true)
,您已将true
设置为IsActive
属性的默认值。因此,在种子数据中-
modelBuilder.Entity<Job>().HasData(
new Job() { IsActive = true });
将值设置为IsActive
(无论值是什么都无关紧要),从迁移的角度来看是一种变化,即使数据在两次迁移之间没有变化。
编辑-解决方案:
设置列默认值的要求始终是有效要求。因此,您可能要考虑更改的另一件事是数据播种方法。
您现在使用的播种方法完全由迁移本身管理,并且有一些限制-Limitations of model seed data
您可以使用Custom initialization logic播种与迁移无关的数据。