执行 Migrations EF core 2.0 时出错,将 Identity id 从 string 更改为 int

Error while doing Migrations EF core 2.0, changing Identity id from string to int

场景:

我从同事那里收到了 ASP.NET CORE 中自动生成的项目。 Account/Manage 服务有自动生成的代码。此代码包括 ApplicationUser Class、DBContext 和带有 00000000000000_CreateIdentitySchema.cs 和 20180323155805_Snapshot.cs 的迁移文件夹。我一直在尝试将我的用户 class 更改为具有整数 ID。为此,我向 IdentityUser 添加了泛型:

public class ApplicationUser : IdentityUser**<int>**
{
}

我还必须创建 ApplicationRole class,因为之前它已在迁移文件中创建。

public class ApplicationRole : IdentityRole<int>
{
}

我也更改了上下文:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, 
    **ApplicationRole, int**>

在迁移文件中,创建了登录方案。添加更改后,我添加了新的迁移。在添加迁移期间我收到此错误:

要更改列的 IDENTITY 属性,需要删除并重新创建该列。

您需要更新生成的迁移才能分步进行。用以下操作替换 AlterColumn 调用:

  1. 添加具有临时名称的新列
  2. 删除原始列
  3. 使用原始列名称重命名新列

您可能还必须重建(删除并re-create)引用该列的所有约束。

这不是微不足道的,这就是 EF 目前不处理它的原因。功能请求 #329 是关于更新 EF 以自动处理此问题。

我创建了一个迁移脚本来完成这项工作。首先我生成了脚本并做了一些修改。

            migrationBuilder.DropForeignKey(name: "FK_AspNetUserTokens_AspNetUsers_UserId", table: "AspNetUserTokens");
            migrationBuilder.DropForeignKey(name: "FK_AspNetUserRoles_AspNetUsers_UserId", table: "AspNetUserRoles");
            migrationBuilder.DropForeignKey(name: "FK_AspNetUserLogins_AspNetUsers_UserId", table: "AspNetUserLogins");
            migrationBuilder.DropForeignKey(name: "FK_AspNetUserClaims_AspNetUsers_UserId", table: "AspNetUserClaims");
            migrationBuilder.DropPrimaryKey(name: "PK_AspNetUsers", table: "AspNetUsers");

            migrationBuilder.DropForeignKey(name: "FK_AspNetUserRoles_AspNetRoles_RoleId", table: "AspNetUserRoles");
            migrationBuilder.DropForeignKey(name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", table: "AspNetRoleClaims");
            migrationBuilder.DropPrimaryKey(name: "PK_AspNetRoles", table: "AspNetRoles");

            migrationBuilder.DropPrimaryKey(name: "PK_AspNetUserTokens", table: "AspNetUserTokens");

            migrationBuilder.DropPrimaryKey(name: "PK_AspNetUserRoles", table: "AspNetUserRoles");

            migrationBuilder.AddColumn<int>(name: "Idtmp", table: "AspNetUsers").Annotation("SqlServer:Identity", "1, 1"); ;
            migrationBuilder.DropColumn(name: "Id", table: "AspNetUsers");
            migrationBuilder.RenameColumn(name: "IdTmp", table: "AspNetUsers", "Id");

            migrationBuilder.AddColumn<int>(name: "Idtmp", table: "AspNetRoles").Annotation("SqlServer:Identity", "1, 1"); ;
            migrationBuilder.DropColumn(name: "Id", table: "AspNetRoles");
            migrationBuilder.RenameColumn(name: "IdTmp", table: "AspNetRoles", "Id");

            migrationBuilder.AlterColumn<int>(name: "UserId", table: "AspNetUserTokens", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");
            migrationBuilder.AlterColumn<int>(name: "RoleId", table: "AspNetUserRoles", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");
            migrationBuilder.AlterColumn<int>(name: "UserId", table: "AspNetUserRoles", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");
            migrationBuilder.AlterColumn<int>(name: "UserId", table: "AspNetUserLogins", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");
            migrationBuilder.AlterColumn<int>(name: "UserId", table: "AspNetUserClaims", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");
            migrationBuilder.AlterColumn<int>(name: "RoleId", table: "AspNetRoleClaims", nullable: false, oldClrType: typeof(string), oldType: "nvarchar(450)");

            migrationBuilder.AddPrimaryKey(name: "PK_AspNetUserRoles", table: "AspNetUserRoles", columns:new[] { "UserId", "RoleId"});

            migrationBuilder.AddPrimaryKey(name: "PK_AspNetUserTokens", table: "AspNetUserTokens", columns:new[] { "UserId", "LoginProvider", "Name" });

            migrationBuilder.AddPrimaryKey(name: "PK_AspNetRoles", table: "AspNetRoles", column: "Id");
            migrationBuilder.AddForeignKey(name: "FK_AspNetUserRoles_AspNetRoles_RoleId", table: "AspNetUserRoles", column: "RoleId", principalTable: "AspNetRoles", principalColumn: "Id", onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", table: "AspNetRoleClaims", column: "RoleId", principalTable: "AspNetRoles", principalColumn: "Id", onDelete: ReferentialAction.Cascade);


            migrationBuilder.AddPrimaryKey(name: "PK_AspNetUsers", table: "AspNetUsers", column: "Id");
            migrationBuilder.AddForeignKey(name: "FK_AspNetUserTokens_AspNetUsers_UserId", table: "AspNetUserTokens", column: "UserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(name: "FK_AspNetUserRoles_AspNetUsers_UserId", table: "AspNetUserRoles", column: "UserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(name: "FK_AspNetUserLogins_AspNetUsers_UserId", table: "AspNetUserLogins", column: "UserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(name: "FK_AspNetUserClaims_AspNetUsers_UserId", table: "AspNetUserClaims", column: "UserId", principalTable: "AspNetUsers", principalColumn: "Id", onDelete: ReferentialAction.Cascade);

使用CLI命令解决

dotnet ef migrations add CreateIdentitySchema
dotnet ef database update