2016-03-31 15 views
5

Tôi đã chơi xung quanh việc di chuyển một ứng dụng hiện có đang chạy trên MVC5 với ASP.NET Identity 2.2.0 gặp khó khăn trong việc tìm kiếm thông tin phù hợp, tôi ' d muốn hỏi làm thế nào bạn có nghĩa vụ phải làm điều này di cư?Cách di chuyển lược đồ cơ sở dữ liệu từ Identity 2.2.0 đến 3.0.0-rc1-end

Tôi đã sử dụng một vài giờ về vấn đề này và đã tìm thấy giải pháp cho phép tôi đăng nhập bằng Identity 3.0.0-rc1-final với ef7 trên cơ sở dữ liệu cũ nhưng đã di chuyển của tôi.

Tôi sẽ đăng những gì tôi đã làm như một câu trả lời, nhưng tôi rất giống như cảm hứng hoặc những cách khác để thực hiện nó.

Trả lời

3

Trước tiên tôi tạo ra một sự chuyển đổi mới với lệnh sau

dnx ef migration add MigrateIdentityFrameworkFrom2to3 

này tạo ra hai tập tin trong thư mục Migrations

  • XYZ_MigrateIdentityFrameworkFrom2to3.cs
  • ApplicationDbContextModelSnapshot.cs

Ảnh chụp nhanh giống với ef6, mô tả về cơ sở dữ liệu của bạn trông như thế nào. tệp khác là di chuyển thực tế có chứa các lệnh Lên và Xuống để di chuyển cơ sở dữ liệu của bạn.

Những vấn đề với việc chuyển đổi sang Identity schema 3.0.0-rc1 kết dường như là

  • AspNetRoles hai cột mới cơ sở dữ liệu (ConcurrencyStamp, NormalizedName)
  • AspNetUsers 4 cột mới (ConcurrencyStamp, LockoutEnd, NormalizedEmail, NormalizedUserName)
  • New Table (AspNetRoleClaims)

và nói chung khóa chính trên AspNetUsers và AspNetRole và Ngoại Ke ys để theese bảng đã thay đổi chiều dài, 128-450

Sau đây là Up và lệnh Xuống tôi đã sử dụng để có thể đăng nhập vào ứng dụng MVC6 tôi:

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"); 
} 
+0

Thực sự có hoạt động không? Còn mật khẩu thì sao? Bạn vẫn có thể đăng nhập bằng cùng một mật khẩu hay nó cần phải được tạo lại bằng cách nào đó? –

+0

Không chắc chắn về mật khẩu, tôi chủ yếu sử dụng các nhà cung cấp đăng nhập bên ngoài và chỉ xác minh rằng họ đã làm việc :) – thmsn

0

Dưới đây là một kịch bản SQL để chuyển đổi cơ sở dữ liệu Identity 2 thành Identity Core (hoặc Identity 3 nếu bạn thích). Ghi chú:

Tập lệnh này được tạo bằng công cụ So sánh lược đồ Visual Studio và sau đó được sửa đổi bằng tay. Mục tiêu của tập lệnh là di chuyển lược đồ mà không làm rơi bảng AspNetUsers. Các bảng khác bị bỏ và tái tạo trong quá trình và dữ liệu được sao chép. Nếu bạn có sửa đổi cho các bảng khác với bảng người dùng hoặc nếu bạn đã sửa đổi PK của bảng người dùng, bạn nên sửa đổi kịch bản cho phù hợp. Có một số thay đổi so với lược đồ mặc định liên quan đến kích thước PK.

  • Bảng người dùng có PK của NVARCHAR (128) vì nó có trong Danh tính 2 chứ không phải NVARCHAR (450) mà Danh tính 3 sử dụng. Tất cả mối quan hệ trong các bảng khác cũng được thay đổi thành NVARCHAR (128)

  • Bảng vai trò có PK của NVARCHAR (128). Đã có một số cảnh báo liên quan đến kích thước khóa tối đa vượt quá 900 byte cho các khóa bao gồm id vai trò.

  • Vẫn còn một số cảnh báo liên quan đến nhà cung cấp đăng nhập có khóa dài hơn nhưng tôi cho rằng đó là rủi ro hợp lý để ProviderKey có 450 ký tự vì nhà cung cấp bên ngoài thực tế có thể sử dụng các khóa lớn. Lưu ý rằng lược đồ ASP.NET Identity 3 mặc định có các khóa chính lớn hơn.

Tôi đã xuất bản tập lệnh tại đây - https://github.com/Eirenarch/Identity2to3 Tôi có thể sửa đổi phiên bản này nếu tôi cần thêm thay đổi hoặc phát hiện lỗi.

PRINT N'Dropping [dbo].[AspNetUserClaims].[IX_UserId]...'; 
GO 
DROP INDEX [IX_UserId] ON [dbo].[AspNetUserClaims]; 
GO 

PRINT N'Dropping [dbo].[AspNetUserLogins].[IX_UserId]...'; 
GO 
DROP INDEX [IX_UserId] ON [dbo].[AspNetUserLogins]; 
GO 


PRINT N'Dropping [dbo].[AspNetUserRoles].[IX_RoleId]...'; 
GO 
DROP INDEX [IX_RoleId] ON [dbo].[AspNetUserRoles]; 
GO 


PRINT N'Dropping [dbo].[AspNetUserRoles].[IX_UserId]...'; 
GO 
DROP INDEX [IX_UserId] ON [dbo].[AspNetUserRoles]; 
GO 


PRINT N'Dropping [dbo].[FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserRoles] DROP CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId]; 
GO 


PRINT N'Dropping [dbo].[FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserClaims] DROP CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId]; 
GO 


PRINT N'Dropping [dbo].[FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserLogins] DROP CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId]; 
GO 


PRINT N'Dropping [dbo].[FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserRoles] DROP CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId]; 
GO 


PRINT N'Starting rebuilding table [dbo].[AspNetRoles]...'; 
GO 
BEGIN TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

SET XACT_ABORT ON; 

CREATE TABLE [dbo].[tmp_ms_xx_AspNetRoles] (
    [Id]    NVARCHAR (128) NOT NULL, 
    [ConcurrencyStamp] NVARCHAR (MAX) NULL, 
    [Name]    NVARCHAR (256) NULL, 
    [NormalizedName] NVARCHAR (256) NULL, 
    CONSTRAINT [tmp_ms_xx_constraint_PK_AspNetRoles1] PRIMARY KEY CLUSTERED ([Id] ASC) 
); 

IF EXISTS (SELECT TOP 1 1 
      FROM [dbo].[AspNetRoles]) 
    BEGIN 
     INSERT INTO [dbo].[tmp_ms_xx_AspNetRoles] ([Id], [Name], [NormalizedName]) 
     SELECT [Id], 
       [Name], 
       UPPER([Name]) 
     FROM  [dbo].[AspNetRoles] 
     ORDER BY [Id] ASC; 
    END 

DROP TABLE [dbo].[AspNetRoles]; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_AspNetRoles]', N'AspNetRoles'; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_constraint_PK_AspNetRoles1]', N'PK_AspNetRoles', N'OBJECT'; 

COMMIT TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 


GO 
PRINT N'Creating [dbo].[AspNetRoles].[RoleNameIndex]...'; 


GO 
CREATE NONCLUSTERED INDEX [RoleNameIndex] 
    ON [dbo].[AspNetRoles]([NormalizedName] ASC); 


GO 
PRINT N'Starting rebuilding table [dbo].[AspNetUserClaims]...'; 


GO 
BEGIN TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

SET XACT_ABORT ON; 

CREATE TABLE [dbo].[tmp_ms_xx_AspNetUserClaims] (
    [Id]   INT   IDENTITY (1, 1) NOT NULL, 
    [ClaimType] NVARCHAR (MAX) NULL, 
    [ClaimValue] NVARCHAR (MAX) NULL, 
    [UserId]  NVARCHAR (128) NOT NULL, 
    CONSTRAINT [tmp_ms_xx_constraint_PK_AspNetUserClaims1] PRIMARY KEY CLUSTERED ([Id] ASC) 
); 

IF EXISTS (SELECT TOP 1 1 
      FROM [dbo].[AspNetUserClaims]) 
    BEGIN 
     SET IDENTITY_INSERT [dbo].[tmp_ms_xx_AspNetUserClaims] ON; 
     INSERT INTO [dbo].[tmp_ms_xx_AspNetUserClaims] ([Id], [UserId], [ClaimType], [ClaimValue]) 
     SELECT [Id], 
       [UserId], 
       [ClaimType], 
       [ClaimValue] 
     FROM  [dbo].[AspNetUserClaims] 
     ORDER BY [Id] ASC; 
     SET IDENTITY_INSERT [dbo].[tmp_ms_xx_AspNetUserClaims] OFF; 
    END 

DROP TABLE [dbo].[AspNetUserClaims]; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_AspNetUserClaims]', N'AspNetUserClaims'; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_constraint_PK_AspNetUserClaims1]', N'PK_AspNetUserClaims', N'OBJECT'; 

COMMIT TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 


GO 
PRINT N'Creating [dbo].[AspNetUserClaims].[IX_AspNetUserClaims_UserId]...'; 


GO 
CREATE NONCLUSTERED INDEX [IX_AspNetUserClaims_UserId] 
    ON [dbo].[AspNetUserClaims]([UserId] ASC); 


GO 
PRINT N'Starting rebuilding table [dbo].[AspNetUserLogins]...'; 


GO 
BEGIN TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

SET XACT_ABORT ON; 

CREATE TABLE [dbo].[tmp_ms_xx_AspNetUserLogins] (
    [LoginProvider]  NVARCHAR (128) NOT NULL, 
    [ProviderKey]   NVARCHAR (450) NOT NULL, 
    [ProviderDisplayName] NVARCHAR (MAX) NULL, 
    [UserId]    NVARCHAR (128) NOT NULL, 
    CONSTRAINT [tmp_ms_xx_constraint_PK_AspNetUserLogins1] PRIMARY KEY CLUSTERED ([LoginProvider] ASC, [ProviderKey] ASC) 
); 

IF EXISTS (SELECT TOP 1 1 
      FROM [dbo].[AspNetUserLogins]) 
    BEGIN 
     INSERT INTO [dbo].[tmp_ms_xx_AspNetUserLogins] ([LoginProvider], [ProviderKey], [ProviderDisplayName], [UserId]) 
     SELECT [LoginProvider], 
       [ProviderKey], 
       [LoginProvider] AS [ProviderDisplayName], 
       [UserId] 
     FROM  [dbo].[AspNetUserLogins] 
     ORDER BY [LoginProvider] ASC, [ProviderKey] ASC; 
    END 

DROP TABLE [dbo].[AspNetUserLogins]; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_AspNetUserLogins]', N'AspNetUserLogins'; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_constraint_PK_AspNetUserLogins1]', N'PK_AspNetUserLogins', N'OBJECT'; 

COMMIT TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 


GO 
PRINT N'Creating [dbo].[AspNetUserLogins].[IX_AspNetUserLogins_UserId]...'; 


GO 
CREATE NONCLUSTERED INDEX [IX_AspNetUserLogins_UserId] 
    ON [dbo].[AspNetUserLogins]([UserId] ASC); 


GO 
PRINT N'Starting rebuilding table [dbo].[AspNetUserRoles]...'; 


GO 
BEGIN TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

SET XACT_ABORT ON; 

CREATE TABLE [dbo].[tmp_ms_xx_AspNetUserRoles] (
    [UserId] NVARCHAR (128) NOT NULL, 
    [RoleId] NVARCHAR (128) NOT NULL, 
    CONSTRAINT [tmp_ms_xx_constraint_PK_AspNetUserRoles1] PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC) 
); 

IF EXISTS (SELECT TOP 1 1 
      FROM [dbo].[AspNetUserRoles]) 
    BEGIN 
     INSERT INTO [dbo].[tmp_ms_xx_AspNetUserRoles] ([UserId], [RoleId]) 
     SELECT [UserId], 
       [RoleId] 
     FROM  [dbo].[AspNetUserRoles] 
     ORDER BY [UserId] ASC, [RoleId] ASC; 
    END 

DROP TABLE [dbo].[AspNetUserRoles]; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_AspNetUserRoles]', N'AspNetUserRoles'; 

EXECUTE sp_rename N'[dbo].[tmp_ms_xx_constraint_PK_AspNetUserRoles1]', N'PK_AspNetUserRoles', N'OBJECT'; 

COMMIT TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 


GO 
PRINT N'Creating [dbo].[AspNetUserRoles].[IX_AspNetUserRoles_RoleId]...'; 


GO 
CREATE NONCLUSTERED INDEX [IX_AspNetUserRoles_RoleId] 
    ON [dbo].[AspNetUserRoles]([RoleId] ASC); 


GO 
PRINT N'Creating [dbo].[AspNetUserRoles].[IX_AspNetUserRoles_UserId]...'; 


GO 
CREATE NONCLUSTERED INDEX [IX_AspNetUserRoles_UserId] 
    ON [dbo].[AspNetUserRoles]([UserId] ASC); 


GO 

-- CHANGE THE REST OF THE SCRIPT! We should NOT drop AspNetUsers 
PRINT N'Starting rebuilding table [dbo].[AspNetUsers]...'; 


GO 
BEGIN TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

SET XACT_ABORT ON; 

ALTER TABLE [dbo].[AspNetUsers] 
ADD [ConcurrencyStamp] NVARCHAR(MAX) NULL 
GO 

ALTER TABLE [dbo].[AspNetUsers] 
ADD [LockoutEnd] DATETIMEOFFSET(7) NULL 
GO 

ALTER TABLE [dbo].[AspNetUsers] 
ADD [NormalizedEmail] NVARCHAR(256) NULL 
GO 

ALTER TABLE [dbo].[AspNetUsers] 
ADD [NormalizedUserName] NVARCHAR(256) NULL 
GO 

DROP INDEX [UserNameIndex] ON [dbo].[AspNetUsers]; 
GO 

UPDATE [dbo].[AspNetUsers] 
SET [NormalizedEmail] = UPPER([Email]), [NormalizedUserName] = UPPER([UserName]) 
GO 

COMMIT TRANSACTION; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED; 
GO 

PRINT N'Creating [dbo].[AspNetUsers].[EmailIndex]...'; 
GO 
CREATE NONCLUSTERED INDEX [EmailIndex] 
    ON [dbo].[AspNetUsers]([NormalizedEmail] ASC); 
GO 


PRINT N'Creating [dbo].[AspNetUsers].[UserNameIndex]...'; 
GO 
CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex] 
    ON [dbo].[AspNetUsers]([NormalizedUserName] ASC); 
GO 


PRINT N'Creating [dbo].[AspNetRoleClaims]...'; 
GO 
CREATE TABLE [dbo].[AspNetRoleClaims] (
    [Id]   INT   IDENTITY (1, 1) NOT NULL, 
    [ClaimType] NVARCHAR (MAX) NULL, 
    [ClaimValue] NVARCHAR (MAX) NULL, 
    [RoleId]  NVARCHAR (128) NOT NULL, 
    CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY CLUSTERED ([Id] ASC) 
); 
GO 


PRINT N'Creating [dbo].[AspNetRoleClaims].[IX_AspNetRoleClaims_RoleId]...'; 
GO 
CREATE NONCLUSTERED INDEX [IX_AspNetRoleClaims_RoleId] 
    ON [dbo].[AspNetRoleClaims]([RoleId] ASC); 
GO 


PRINT N'Creating [dbo].[AspNetUserTokens]...'; 
GO 
CREATE TABLE [dbo].[AspNetUserTokens] (
    [UserId]  NVARCHAR (128) NOT NULL, 
    [LoginProvider] NVARCHAR (128) NOT NULL, 
    [Name]   NVARCHAR (450) NOT NULL, 
    [Value]   NVARCHAR (MAX) NULL, 
    CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY CLUSTERED ([UserId] ASC, [LoginProvider] ASC, [Name] ASC) 
); 
GO 


PRINT N'Creating [dbo].[FK_AspNetUserClaims_AspNetUsers_UserId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserClaims] WITH NOCHECK 
    ADD CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE; 
GO 

PRINT N'Creating [dbo].[FK_AspNetUserLogins_AspNetUsers_UserId]...'; 
GO 


ALTER TABLE [dbo].[AspNetUserLogins] WITH NOCHECK 
    ADD CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE; 
GO 


PRINT N'Creating [dbo].[FK_AspNetUserRoles_AspNetRoles_RoleId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserRoles] WITH NOCHECK 
    ADD CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[AspNetRoles] ([Id]) ON DELETE CASCADE; 
GO 


PRINT N'Creating [dbo].[FK_AspNetUserRoles_AspNetUsers_UserId]...'; 
GO 
ALTER TABLE [dbo].[AspNetUserRoles] WITH NOCHECK 
    ADD CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE; 
GO 


PRINT N'Creating [dbo].[FK_AspNetRoleClaims_AspNetRoles_RoleId]...'; 
GO 
ALTER TABLE [dbo].[AspNetRoleClaims] WITH NOCHECK 
    ADD CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[AspNetRoles] ([Id]) ON DELETE CASCADE; 
GO 


PRINT N'Checking existing data against newly created constraints'; 
GO 
ALTER TABLE [dbo].[AspNetUserClaims] WITH CHECK CHECK CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId]; 

ALTER TABLE [dbo].[AspNetUserLogins] WITH CHECK CHECK CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId]; 

ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId]; 

ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK CHECK CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId]; 

ALTER TABLE [dbo].[AspNetRoleClaims] WITH CHECK CHECK CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId]; 


GO 
PRINT N'Update complete.'; 
Các vấn đề liên quan