尽管没有进行任何更改,为什么 EF Core 在每次迁移时都会更新种子布尔字段?

Kyl*_*ams 5 entity-framework-core .net-core entity-framework-core-3.1

这是 EF Core 3.1。我有几个带有布尔字段 的模型,IsActive定义如下:

public class Job
{
    public bool? IsActive { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的种子数据如下所示:

modelBuilder.Entity<Job>()
    .Property(e => e.IsActive)
    .HasDefaultValue(true);

modelBuilder.Entity<Job>().HasData(
    new Job() { IsActive = true });
Run Code Online (Sandbox Code Playgroud)

每次我创建迁移(包括如果我运行未进行任何更改的迁移,这应该生成一个空迁移),它都会调用UpdateData上面的字段,如下所示:

migrationBuilder.UpdateData(
    table: "Jobs",
    keyColumn: "id",
    keyValue: 1L,
    column: "IsActive",
    value: true);
Run Code Online (Sandbox Code Playgroud)

我还在TodoApi 应用程序中复制了此行为,并为任何对更多详细信息感兴趣的人设置了 GitHub 存储库

我知道当种子数据由函数生成时会发生这种情况,或者类似的结果DateTime.Now。我不明白当在播种期间为该列分配原始布尔值时会发生这种情况。

此行为似乎与问题 #13047非常相似,“将 BoolToStringConverter 与 HasData 一起使用时生成不正确的 UpdateData 操作”,但该问题已在 EF Core 2.2 中修复

ati*_*yar 3

原因是HasDefaultValue(true)以下模型配置代码中的调用 -

modelBuilder.Entity<Job>()
    .Property(e => e.IsActive)
    .HasDefaultValue(true);
Run Code Online (Sandbox Code Playgroud)

每当您使用该方法为属性设置默认值时HasDefaultValue()值就是要为数据库表中的相应列设置的值。

使用HasDefaultValue(true),您已将属性设置true为默认值IsActive。因此,在种子数据中 -

modelBuilder.Entity<Job>().HasData(
    new Job() { IsActive = true });
Run Code Online (Sandbox Code Playgroud)

从迁移的角度来看,将值设置为IsActive(无论值是什么都没关系)是一个更改,即使数据在迁移之间没有更改。

编辑-解决方案是什么:
为列设置默认值的要求始终是有效的要求。因此,您可能考虑改变的另一件事是数据播种方法。

您现在使用的播种方法完全由迁移本身管理,并且它有一些限制 -模型种子数据的限制

您可以使用自定义初始化逻辑来播种与迁移无关的数据。