Entity Framework Core - 当模型更改时,早期数据迁移会中断

Dan*_*oft 4 c# entity-framework entity-framework-core .net-core

我们正在使用 .NET Core、EF Core 和 Postgres 启动一个新应用程序 - 我们真的很喜欢这些迁移:-)

但是,我发现了一个我不知道如何解决的问题。在我们的一些迁移中,我们使用DbContext来加载记录、运行一些业务逻辑并重新保存记录。我们也在database.Context.Migrate()Web 服务器启动时运行,因此它始终运行。

这一切都运行良好(到目前为止)。

不幸的是,它一直有效,直到模型稍后更改为止。考虑以下迁移顺序:

  1. 创建CustomerOrder、 和OrderLine模型。添加架构迁移以加载结构

  2. 业务规则发生变化,所以我们需要Order根据一些业务逻辑在记录上设置一个值。我们创建一个数据迁移,在其中加载DbContext、运行代码并运行SaveChangesAsync()

    至此,一切都很好。

  3. 我们需要向记录添加带有新字段的架构迁移Customer

在这里,事情破裂了。如果数据库尚未应用迁移 2,则该Migrate()命令会在应用迁移 2 时出错,EF 正在尝试生成包含 3 中的新字段的 select 语句。

但我不确定问题实际上出在这个过程中:我们不应该DbContext在迁移中使用(和手动编写 SQL 语句)吗?我们是否应该明确地对读取的每条记录进行预测,以便我们确切地知道我们在做什么?

还有别的事吗?

Cal*_*leb 5

在您的示例中,1 和 3 是架构迁移,2 是数据迁移。

由于 Entity Framework Core 将根据代码中的当前模型而不是数据库的当前状态生成查询,因此有两种选项用于处理数据迁移。

  1. 通过架构迁移按顺序执行数据迁移

    使用DapperADO.NET之类的工具根据写入迁移时的架构执行数据迁移。您可以DbConnection使用以下方法从 EF Context 获取对象context.Database.GetDbConnection()

    优点:迁移代码永远不需要更改

    缺点:您将无法获得 EF Core 的任何好处

  2. 架构迁移后执行数据迁移

    EF 按照MigrationAttribute.Id字符串值的升序执行迁移。EF 在调用时根据时间戳生成此值dotnet ef migrations add xxx。您可以更改此属性以确保在所有架构迁移之后运行数据迁移。还可以更改文件名以提高可读性,以便它们保持应用的顺序。

    优点:您可以获得 EF Core 的所有优势

    缺点:如果将来架构发生变化,例如删除数据迁移中引用的列,您将需要修改迁移

    更改示例MigrationAttribute.Id

// change
[Migration("20191002171530_DataMigration")]
// to
[Migration("99999999000001_DataMigration")]
Run Code Online (Sandbox Code Playgroud)