Add-Migration 命令使用什么来比较模式?

What does Add-Migration command use to compare schemas?

我正在重命名几个表和列。由于我不想丢失现有数据,因此我从头开始创建了一个迁移。

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.RenameTable(name: "Providers", schema: "dbo", newName: "Vendors", newSchema: "dbo");
    migrationBuilder.RenameTable(name: "ProviderContacts", schema: "dbo", newName: "VendorContacts", newSchema: "dbo");
    migrationBuilder.RenameColumn(name: "ProviderId", table: "AspNetUsers", newName: "VendorId", schema: "dbo");
    migrationBuilder.RenameColumn(name: "ProviderId", table: "VendorContacts", newName: "VendorId", schema: "dbo");
    migrationBuilder.RenameColumn(name: "ProviderId", table: "Locations", newName: "VendorId", schema: "dbo");
}

我然后运行Update-Database。但这仍然留下一堆索引和外键也应该重命名。所以我使用 Add-Migration 命令来更新所有剩余的更改。

但我注意到新迁移似乎正在删除并重新创建我的自定义迁移已重命名的表和列。

migrationBuilder.DropTable(
    name: "ProviderContacts");

migrationBuilder.DropTable(
    name: "Providers");

migrationBuilder.DropIndex(
    name: "IX_Locations_ProviderId",
    table: "Locations");

migrationBuilder.DropIndex(
    name: "IX_AspNetUsers_ProviderId",
    table: "AspNetUsers");

migrationBuilder.DropColumn(
    name: "ProviderId",
    table: "Locations");

migrationBuilder.DropColumn(
    name: "ProviderId",
    table: "AspNetUsers");

我的问题是:Add-Migration 命令比较的是什么?它是在查看数据库还是其他什么?为什么它没有识别出这些表和列已重命名?

如何让它识别自定义迁移中的更改?

EF 在将您的 C# 模型与数据库模型进行比较时,不会使用您的实际数据库架构或迁移文件的内容。

当您 运行 您的更新数据库 Entity Framework 序列化您的 C# 模型并将其存储在 __MigrationHistory table.

您在 C# 模型中更改了 类 的名称,然后调用 Add-Migration,因此 EF 发现模型已更改并创建迁移以进行更改。 如果您不喜欢它进行更改的方式,或者您需要更新数据以使迁移工作,您可以更改它创建的迁移。

因此通常您不会在更改 C# 类 之前创建初始迁移。您应该先更改 C# 类。然后 Add-Migration 并更改生成的迁移,以便在您调用 Update-Database 时重命名 table 而不是删除它们

在您当前的情况下,您可以从第二次迁移中删除删除和重新创建语句,因为重命名已经发生

在 EF Core 中,Update-Database 使用 IMigrationsAssembly 服务来发现编译到程序集中的迁移。它使用另一项服务获取已针对此数据库 运行 的迁移列表。随着迁移的执行,迁移列表会在 table 中更新。该进程不知道或不关心您的数据库模型的状态,它不会导致您的数据库模型发生任何变化。该过程旨在针对其他数据库工作,而无需了解您的开发环境。

运行 Add-Migration 使用 IMigrationsAssembly 服务加载先前已编译到程序集中的 ModelSnapshot,以及上下文中的模型 OnModelCreating 方法。然后它两次使用 IMigrationsModelDiffer 服务来比较两个模型并生成向上和向下迁移例程。然后将新迁移和 ModelSnapshot 序列化回源代码并写入磁盘。此进程对任何数据库的状态或先前迁移中的操作列表一无所知。

换句话说,Add-Migration 不关心您是否编写了另一个迁移。它仍然会比较这两个模型。迁移差异并不完美,如果 table 之前和之后差异太大,它将生成删除和创建步骤。

另一种选择是一次执行一个更改,为每个步骤创建新的迁移。然后将 Up & Down 方法合并到最后一次迁移中。并删除其余部分。