Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Scenario:

I have received auto generated project in ASP.NET CORE from my colleague. There is auto-generated code for Account/Manage service. This code includes ApplicationUser Class, DBContext and migration folder with 00000000000000_CreateIdentitySchema.cs and 20180323155805_Snapshot.cs. I have been trying to change my User class to have integer id. To do that I added generic to IdentityUser:

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

I also had to create ApplicationRole class, because before it had been created in migration files.

public class ApplicationRole : IdentityRole<int>
{
}

I also changed my context:

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

In migration files, there is created login scheme. After my changes addition, I add new migrations. During adding migration i received this error:

To change the IDENTITY property of a column, the column needs to be dropped and recreated.

like image 210
zolty13 Avatar asked Mar 23 '18 16:03

zolty13


2 Answers

You'll need to update the generated migration to do it in steps. Replace the AlterColumn call with the following operations:

  1. Add the new column with a temporary name
  2. Drop the original column
  3. Rename the new column using the original columns name

You may also have to rebuild (drop and re-create) all the constraints that reference the column.

It's not trivial, which is why EF currently doesn't handle it. Feature request #329 is about updating EF to handle this automatically.

like image 77
bricelam Avatar answered Nov 12 '22 10:11

bricelam


I create an migration script what does the job. First I generated the script and made some changes.

            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);

like image 37
Thom Kiesewetter Avatar answered Nov 12 '22 09:11

Thom Kiesewetter