First I generated a new migration with the following command
dnx ef migration add MigrateIdentityFrameworkFrom2to3
This created two files in the Migrations folder
- XYZ_MigrateIdentityFrameworkFrom2to3.cs
- ApplicationDbContextModelSnapshot.cs
The snapshot is the same as with ef6, a description of what your database looks like. another file is the actual migration containing the Up and Down commands to migrate your database.
Problems with switching to the Identity 3.0.0-rc1-final scheme turned out to be
- AspNetRoles Two new database columns (ConcurrencyStamp, NormalizedName)
- AspNetUsers 4 new columns (ConcurrencyStamp, LockoutEnd, NormalizedEmail, NormalizedUserName)
- New table (AspNetRoleClaims)
In general, the primary key on AspNetUsers and AspNetRole and foreign keys to these tables have changed in length, from 128 to 450
The following are the Up and Down commands that I used to enter the MVC6 application:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.DropForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId", "AspNetUserRoles"); migrationBuilder.DropPrimaryKey("PK_dbo.AspNetRoles", "AspNetRoles"); migrationBuilder.Sql(@" ALTER TABLE[AspNetRoles] ALTER COLUMN[Id] NVARCHAR(450) NOT NULL ALTER TABLE[AspNetUserRoles] ALTER COLUMN[RoleId] NVARCHAR(450) NOT NULL"); migrationBuilder.AddPrimaryKey("PK_dbo.AspNetRoles", "AspNetRoles", "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId", "AspNetUserRoles", "RoleId", "AspNetRoles", principalColumn:"Id"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId", "AspNetUserClaims"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId", "AspNetUserLogins"); migrationBuilder.DropForeignKey("FK_dbo.User_dbo.AspNetUsers_IdentityUser_Id", "User"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId", "AspNetUserRoles"); migrationBuilder.DropPrimaryKey("PK_dbo.AspNetUsers", "AspNetUsers"); migrationBuilder.Sql(@" ALTER TABLE [AspNetUsers] ALTER COLUMN [Id] NVARCHAR(450) NOT NULL ALTER TABLE[AspNetUserRoles] ALTER COLUMN[UserId] NVARCHAR(450) NOT NULL ALTER TABLE[User] ALTER COLUMN[IdentityUser_Id] NVARCHAR(450) NOT NULL ALTER TABLE[AspNetUserLogins] ALTER COLUMN[UserId] NVARCHAR(450) NOT NULL ALTER TABLE[AspNetUserClaims] ALTER COLUMN[UserId] NVARCHAR(450) NOT NULL"); migrationBuilder.AddPrimaryKey("PK_dbo.AspNetUsers", "AspNetUsers", "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId", "AspNetUserRoles", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.User_dbo.AspNetUsers_IdentityUser_Id", "User", "IdentityUser_Id", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId", "AspNetUserLogins", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId", "AspNetUserClaims", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddColumn<string>(name: "ConcurrencyStamp", table: "AspNetRoles", nullable: true); migrationBuilder.AddColumn<string>(name: "NormalizedName", table: "AspNetRoles", nullable: true); migrationBuilder.Sql(@"UPDATE AspNetRoles SET NormalizedName = UPPER(Name)"); migrationBuilder.AddColumn<string>(name: "ConcurrencyStamp", table: "AspNetUsers", nullable: true); migrationBuilder.AddColumn<string>(name: "LockoutEnd", table: "AspNetUsers", nullable: true); migrationBuilder.AddColumn<string>(name: "NormalizedEmail", table: "AspNetUsers", nullable: true); migrationBuilder.AddColumn<string>(name: "NormalizedUserName", table: "AspNetUsers", nullable: true); migrationBuilder.Sql(@"UPDATE AspNetUsers SET NormalizedEmail = UPPER(Email), NormalizedUserName = UPPER(UserName)"); // MVC6 utilizes Email as login by default with forms authentication, and searches for the email in NormalizedUserName, I changed the login formular to utilize UserName instead of email when logging in, alternatively you can put in the email as NormalizedUserName. migrationBuilder.CreateTable( name: "AspNetRoleClaims", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), ClaimType = table.Column<string>(nullable: true), ClaimValue = table.Column<string>(nullable: true), RoleId = table.Column<string>(nullable: false) }, constraints: table => { table.PrimaryKey("PK_IdentityRoleClaim<string>", x => x.Id); table.ForeignKey( name: "FK_IdentityRoleClaim<string>_IdentityRole_RoleId", column: x => x.RoleId, principalTable: "AspNetRoles", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.AddColumn<string>(name: "ProviderDisplayName", table: "AspNetUserLogins", nullable: true); migrationBuilder.DropIndex( name: "RoleNameIndex", table: "AspNetRoles"); migrationBuilder.CreateIndex( name: "RoleNameIndex", table: "AspNetRoles", column: "NormalizedName"); migrationBuilder.CreateIndex( name: "EmailIndex", table: "AspNetUsers", column: "NormalizedEmail"); migrationBuilder.DropIndex( name: "UserNameIndex", table: "AspNetUsers"); migrationBuilder.CreateIndex( name: "UserNameIndex", table: "AspNetUsers", column: "NormalizedUserName"); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId", "AspNetUserRoles"); migrationBuilder.DropPrimaryKey("PK_dbo.AspNetRoles", "AspNetRoles"); migrationBuilder.Sql(@"ALTER TABLE [AspNetRoles] ALTER COLUMN [Id] NVARCHAR(128) NOT NULL ALTER TABLE[AspNetUserRoles] ALTER COLUMN[RoleId] NVARCHAR(128) NOT NULL"); migrationBuilder.AddPrimaryKey("PK_dbo.AspNetRoles", "AspNetRoles", "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId", "AspNetUserRoles", "RoleId", "AspNetRoles", principalColumn: "Id"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId", "AspNetUserClaims"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId", "AspNetUserLogins"); migrationBuilder.DropForeignKey("FK_dbo.User_dbo.AspNetUsers_IdentityUser_Id", "User"); migrationBuilder.DropForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId", "AspNetUserRoles"); migrationBuilder.DropPrimaryKey("PK_dbo.AspNetUsers", "AspNetUsers"); migrationBuilder.Sql(@"ALTER TABLE [AspNetUsers] ALTER COLUMN [Id] NVARCHAR(128) NOT NULL ALTER TABLE[AspNetUserRoles] ALTER COLUMN[UserId] NVARCHAR(128) NOT NULL ALTER TABLE[User] ALTER COLUMN[IdentityUser_Id] NVARCHAR(128) NOT NULL ALTER TABLE[AspNetUserLogins] ALTER COLUMN[UserId] NVARCHAR(128) NOT NULL ALTER TABLE[AspNetUserClaims] ALTER COLUMN[UserId] NVARCHAR(128) NOT NULL"); migrationBuilder.AddPrimaryKey("PK_dbo.AspNetUsers", "AspNetUsers", "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId", "AspNetUserRoles", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.User_dbo.AspNetUsers_IdentityUser_Id", "User", "IdentityUser_Id", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId", "AspNetUserLogins", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.AddForeignKey("FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId", "AspNetUserClaims", "UserId", "AspNetUsers", principalColumn: "Id"); migrationBuilder.DropTable("AspNetRoleClaims"); migrationBuilder.DropColumn(name: "ConcurrencyStamp", table: "AspNetRoles"); migrationBuilder.DropColumn(name: "NormalizedName", table: "AspNetRoles"); migrationBuilder.DropColumn(name: "ConcurrencyStamp", table: "AspNetUsers"); migrationBuilder.DropColumn(name: "LockoutEnd", table: "AspNetUsers"); migrationBuilder.DropColumn(name: "NormalizedEmail", table: "AspNetUsers"); migrationBuilder.DropColumn(name: "NormalizedUserName", table: "AspNetUsers"); migrationBuilder.DropColumn(name: "ProviderDisplayName", table: "AspNetUserLogins"); migrationBuilder.DropIndex( name: "RoleNameIndex", table: "AspNetRoles"); migrationBuilder.CreateIndex( name: "RoleNameIndex", table: "AspNetRoles", column: "Name"); migrationBuilder.DropIndex( name: "EmailIndex", table: "AspNetUsers"); migrationBuilder.DropIndex( name: "UserNameIndex", table: "AspNetUsers"); migrationBuilder.CreateIndex( name: "UserNameIndex", table: "AspNetUsers", column: "UserName"); }