如何修复EntityFrameworkCore中的数据迁移错误?

时间:2019-02-15 12:46:34

标签: entity-framework asp.net-core msbuild entity-framework-core

背景

我有一个现有的dbset,它具有FooCol1字段,该字段最初是字符串数据类型。

public class Foo
{
    [Key]
    public Guid Id { get; set; }
    public string FooCol1 { get; set; }
    public string FooCol2 { get; set; }
    public string FooCol3 { get; set; }
}

我想将其更改为一个int,所以我在EntityFrameworkCore中执行了以下操作:

  1. 添加了一个迁移列,并使用SQL填充了迁移列

型号

public class Foo
{
    [Key]
    public Guid Id { get; set; }
    public string FooCol1 { get; set; }
    public string FooCol2 { get; set; }
    public string FooCol3 { get; set; }
    public int? FooCol1Migration { get; set; } //new migration column
}

迁移

migrationBuilder.AddColumn<int>(
            name: "FooCol1Migration",
            table: "Foos",
            nullable: true);

migrationBuilder.Sql("Update Foos set FooCol1Migration=1"); //script to populate the new migration column
  1. 现在数据在新列中,删除原始属性并重命名迁移列。

型号

public class Foo
{
    [Key]
    public Guid Id { get; set; }
    public string FooCol2 { get; set; }
    public string FooCol3 { get; set; }
    public int? FooCol1 { get; set; } //renamed from FooCol1Migration
}

迁移

EFC提供的原始迁移脚本是更改FooCol1列的数据类型并删除FooCol1Migration列。

我将其更改为重命名,因此它保留了我在步骤1中迁移的数据。

migrationBuilder.DropColumn(
            name: "FooCol1",
            table: "Foos");

migrationBuilder.RenameColumn(
            name: "FooCol1Migration",
            newName: "FooCol1",
            table: "Foos");

我认为这就是我的问题所在。

问题

当我尝试使用Web Deploy将更改发布到我的登台环境时,SQL脚本在确实填充迁移列的那一行上出错了。

我查看了生成的脚本,发现它在这里出错:

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20190212155305_Adding FooCol1Migration field to Foo')
BEGIN
    update Foos Set FooCol1Migration=1
END;

GO

很明显,FooCol1Migration已经不存在了,即使将它包装在一个NOT EXISTS中,SQL Server仍在检查基础数据结构并阻止发布完成。

问题 从这里进行进展的最佳方法是什么,这样我就可以成功发布SQL脚本了?我不想只是重新添加FooCol1Migation列以允许脚本运行。

我正在使用的软件版本

  • Visual Studio 2017 15.7.4
  • Asp.Net Core 2.1.1

1 个答案:

答案 0 :(得分:1)

好的,所以我通过使用存储过程而不是直接运行SQL来执行数据迁移SQL来完成这项工作

migrationBuilder.Sql("Execute sp_executesql \"update Foos Set FooCol1Migration=1\"")

现在生成:

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20190212155305_Adding FooCol1Migration field to Foos')
BEGIN
    Execute sp_executesql "update Foos Set FooCol1Migration=1"
END;

GO

如果有人对我的问题有更好的/替代的解决方案或意见,我仍然很想听听他们。