我一直在使用ASP.NET Identity 2.2.0迁移运行在MVC5上的现有应用程序,但无法找到正确的信息,我想问一下你应该如何进行这种迁移? / p>
我已经花了几个小时来解决这个问题,并找到了一个解决方案,允许我在旧的但迁移的数据库上使用ef7登录Identity 3.0.0-rc1-final。
我会发布我所做的答案,但我非常喜欢灵感或其他方式来完成它。
答案 0 :(得分:3)
首先,我使用以下命令生成了新的迁移
dnx ef migration add MigrateIdentityFrameworkFrom2to3
这会在文件夹迁移
中生成两个文件快照与ef6相同,后者描述了数据库的外观。另一个文件是包含用于迁移数据库的Up和Down命令的实际迁移。
迁移到Identity 3.0.0-rc1-final模式的问题似乎是
一般来说,AspNetUsers和AspNetRole上的主键以及theese表的外键已经改变了长度,从128到450
以下是我以前能够登录MVC6应用程序的Up和Down命令:
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");
}
答案 1 :(得分:1)
这是一个SQL脚本,用于将Identity 2数据库转换为Identity Core(如果您愿意,还可以转换为Identity 3)。注意:
此脚本由Visual Studio架构比较工具生成,然后手动修改。该脚本的目标是在不删除AspNetUsers表的情况下迁移模式。在进程中删除并重新创建其他表,并复制数据。如果您对users表以外的表进行了修改,或者您修改了users表的PK,则应相应地修改脚本。与PK大小相关的默认架构相比,有几处变化。
用户表具有NVARCHAR(128)的PK,因为它在身份2中而不是NVARCHAR(450)中使用Identity 3。其他表中的所有关系也更改为NVARCHAR(128)
角色表的PK值为NVARCHAR(128)。对于包括角色ID的密钥,有几个警告与最大密钥大小超过900字节有关。
还有一些警告与登录提供商有较长的密钥相关,但我认为让ProviderKey为450个字符是合理的风险,因为实际的外部提供商可能使用大密钥。请注意,默认的ASP.NET Identity 3架构具有更大的主键。
我最初在这里发布了脚本 - https://github.com/Eirenarch/Identity2to3如果我需要进一步更改或发现错误,我可能会修改此版本。
{{1}}