如何在现有数据库中创建 ASP.Net Identity 表?
Posted
技术标签:
【中文标题】如何在现有数据库中创建 ASP.Net Identity 表?【英文标题】:How to create ASP.Net Identity tables inside existing database? 【发布时间】:2015-04-22 13:50:14 【问题描述】:我正在构建我的第一个 MVC 5 / Entity Framework 应用程序。我使用数据库优先方法从现有的 SQL 服务器中提取数据。现有 SQL 数据库从单独的 Web 表单 .net 应用程序接收数据。
展望未来,新的 MVC 应用程序和现有的 Web 表单应用程序将共享数据库。
我正在使用 Identity 在 MVC 应用程序中创建用户帐户。所以此时,我的 MVC 应用程序中有 2 个数据连接。一个用于用户帐户,另一个用于现有 SQL 服务器。
这是设置 MVC 项目的最佳方式吗?展望未来,我能否从 Web 表单应用程序访问用户数据库?
我是新手,我想确保我设置正确。
【问题讨论】:
Web 表单可以使用身份。使用 VS2013 创建一个新的 Web Forms 项目并确保选中“个人帐户”。不过,您可能需要升级到 .NET 4.5 才能利用这一点。 您可以将 ASP.Net Identity 表放在现有数据库中 - How to add ASP.NET MVC5 Identity Authentication to existing database 感谢您的快速回复。我知道这是一个新手问题——我还没有发布我的网站,所以用户数据库似乎只存在于我的 MVC 项目中。是否会将用户表添加到现有的 sql server 中,或者这个用户数据库是一个完全独立的数据库?如果是这样,合并这两个数据库是否是最佳做法? 谢谢 - 我按照上面 Win 的链接在我现有的数据库中创建了用户表。完美运行! 【参考方案1】:是否将用户表添加到现有的 sql server 中,或者是 这个用户数据库是一个完全独立的数据库?
您不需要两个数据库 - 您可以在现有数据库中创建身份表。
ASP.Net Identity 使用 Entity Framework Code First。因此,在第一次运行您的应用程序之前,您需要更新与现有数据库相同的连接字符串,该数据库通常位于 ApplicationDbContext 中。
如果您已经有两个独立的数据库并且想要合并它们,您想要使用 RedGate - SQL 比较和数据比较等工具。
合并两个数据库是完全不可能的;如果您有问题,请创建一个单独的问题。
【讨论】:
【参考方案2】:在数据库上运行此 SQL 脚本。
/****** Object: Table [dbo].[AspNetRoles] Script Date: 15-Mar-17 10:27:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetRoles](
[Id] [nvarchar](128) NOT NULL,
[Name] [nvarchar](256) NOT NULL,
CONSTRAINT [PK_dbo.AspNetRoles] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[AspNetUserClaims] Script Date: 15-Mar-17 10:27:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserClaims](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [nvarchar](128) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
CONSTRAINT [PK_dbo.AspNetUserClaims] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[AspNetUserLogins] Script Date: 15-Mar-17 10:27:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserLogins](
[LoginProvider] [nvarchar](128) NOT NULL,
[ProviderKey] [nvarchar](128) NOT NULL,
[UserId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserLogins] PRIMARY KEY CLUSTERED
(
[LoginProvider] ASC,
[ProviderKey] ASC,
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[AspNetUserRoles] Script Date: 15-Mar-17 10:27:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUserRoles](
[UserId] [nvarchar](128) NOT NULL,
[RoleId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUserRoles] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[RoleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[AspNetUsers] Script Date: 15-Mar-17 10:27:06 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[AspNetUsers](
[Id] [nvarchar](128) NOT NULL,
[Email] [nvarchar](256) NULL,
[EmailConfirmed] [bit] NOT NULL,
[PasswordHash] [nvarchar](max) NULL,
[SecurityStamp] [nvarchar](max) NULL,
[PhoneNumber] [nvarchar](max) NULL,
[PhoneNumberConfirmed] [bit] NOT NULL,
[TwoFactorEnabled] [bit] NOT NULL,
[LockoutEndDateUtc] [datetime] NULL,
[LockoutEnabled] [bit] NOT NULL,
[AccessFailedCount] [int] NOT NULL,
[UserName] [nvarchar](256) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[AspNetUserClaims] WITH CHECK ADD CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserClaims] CHECK CONSTRAINT [FK_dbo.AspNetUserClaims_dbo.AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserLogins] WITH CHECK ADD CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserLogins] CHECK CONSTRAINT [FK_dbo.AspNetUserLogins_dbo.AspNetUsers_UserId]
GO
ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId] FOREIGN KEY([RoleId])
REFERENCES [dbo].[AspNetRoles] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetRoles_RoleId]
GO
ALTER TABLE [dbo].[AspNetUserRoles] WITH CHECK ADD CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[AspNetUserRoles] CHECK CONSTRAINT [FK_dbo.AspNetUserRoles_dbo.AspNetUsers_UserId]
GO
【讨论】:
【参考方案3】:使用 DB First,更改连接字符串不会导致 Identity 2.0 在 DB 中创建表。
更正:我最初在身份架构下的数据库中拥有身份表,当我使用以下注册新用户时,新表在 dbo 架构下写入我的数据库。
您必须首先使用 Code First 创建一个虚拟项目,构建并运行该项目,在您的 Web 浏览器中进入正在运行的应用程序,使用虚拟电子邮件和密码注册用户,这将导致 Entity FrameWork Code First( ?) 在您的虚拟数据库中创建所有 Identity 2.0 DB 表。然后,您需要将虚拟表导出到 SQL 脚本,并将它们导入到您想要使用它们的现有数据库中。应该有 5 个表:AspNetUserRoles、AspNetRoles、AspNetUsers、AspNetUserClaims 和 AspNetUserLogins。
我的主要数据库模型有一个 ADO.Net 实体模型(.edmx 文件),并为身份模型创建了另一个 .edmx(我命名为:IdentityDbEntities)。那是你应该从“DefaultConnection”更改连接字符串的时候:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
public ApplicationDbContext()
: base("IdentityDbEntitiesString", throwIfV1Schema: false)
非常重要: 在您的 Web.config 文件中,您必须添加将在上面使用的额外连接字符串。看起来像(我使用的是 SQL Server 开发环境,所以你的连接字符串可能会改变):
<connectionStrings>
<add name="IdentityDbEntitiesString"
connectionString="Data Source=#MyServerAddress#;
Initial Catalog=#DbName#;
Integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
<add name="IdentityDbEntities"
connectionString="metadata=res://*/Models.IdentityModel.csdl|
res://*/Models.IdentityModel.ssdl|
res://*/Models.IdentityModel.msl;
provider=System.Data.SqlClient;
provider connection string="
data source=#MyServerAddress#;
initial catalog=#DbName#;
integrated security=True;multipleactiveresultsets=True;
application name=EntityFramework""
providerName="System.Data.EntityClient" /> </connectionStrings>
#'s 中的任何内容,如 #DbName# 都是您自定义的。
【讨论】:
【参考方案4】:我做了一系列步骤:
第 1 步。 创建一个全新的(临时)项目,使用您现有项目喜欢的模板。创建新项目时,您必须选择选项有Identity,以及Individual...
第 2 步。您已经有一个项目。添加脚手架项目...选择身份...
第三步。打开Package Manager Console
,运行命令
Update-Database
你会在控制台看到这样的(和你的不完全一样,因为我使用的是新版本的 Visual Studio、.NET Core 框架、发布时间等)
Each package is licensed to you by its owner. NuGet is not responsible for, nor does it grant any licenses to, third-party packages. Some packages may include dependencies which are governed by additional licenses. Follow the package source (feed) URL to determine any dependencies.
Package Manager Console Host Version 5.5.0.6293
Type 'get-help NuGet' to see all available NuGet commands.
PM> Update-Database
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.1.1 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (15ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT 1
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Migrations[20402]
Applying migration '00000000000000_CreateIdentitySchema'.
Applying migration '00000000000000_CreateIdentitySchema'.
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetRoles] (
[Id] nvarchar(450) NOT NULL,
[Name] nvarchar(256) NULL,
[NormalizedName] nvarchar(256) NULL,
[ConcurrencyStamp] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetUsers] (
[Id] nvarchar(450) NOT NULL,
[UserName] nvarchar(256) NULL,
[NormalizedUserName] nvarchar(256) NULL,
[Email] nvarchar(256) NULL,
[NormalizedEmail] nvarchar(256) NULL,
[EmailConfirmed] bit NOT NULL,
[PasswordHash] nvarchar(max) NULL,
[SecurityStamp] nvarchar(max) NULL,
[ConcurrencyStamp] nvarchar(max) NULL,
[PhoneNumber] nvarchar(max) NULL,
[PhoneNumberConfirmed] bit NOT NULL,
[TwoFactorEnabled] bit NOT NULL,
[LockoutEnd] datetimeoffset NULL,
[LockoutEnabled] bit NOT NULL,
[AccessFailedCount] int NOT NULL,
CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetRoleClaims] (
[Id] int NOT NULL IDENTITY,
[RoleId] nvarchar(450) NOT NULL,
[ClaimType] nvarchar(max) NULL,
[ClaimValue] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]),
CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetUserClaims] (
[Id] int NOT NULL IDENTITY,
[UserId] nvarchar(450) NOT NULL,
[ClaimType] nvarchar(max) NULL,
[ClaimValue] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]),
CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetUserLogins] (
[LoginProvider] nvarchar(128) NOT NULL,
[ProviderKey] nvarchar(128) NOT NULL,
[ProviderDisplayName] nvarchar(max) NULL,
[UserId] nvarchar(450) NOT NULL,
CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]),
CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetUserRoles] (
[UserId] nvarchar(450) NOT NULL,
[RoleId] nvarchar(450) NOT NULL,
CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]),
CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [AspNetUserTokens] (
[UserId] nvarchar(450) NOT NULL,
[LoginProvider] nvarchar(128) NOT NULL,
[Name] nvarchar(128) NOT NULL,
[Value] nvarchar(max) NULL,
CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]),
CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]);
infoverbose: Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE UNIQUE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL;
infoverbose: Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]);
infoverbose: Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL;
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'00000000000000_CreateIdentitySchema', N'3.1.1');
Done.
PM>
这些 SQL 脚本正是您所需要的。
截图仅用于想法说明
【讨论】:
这真的很接近。对我来说,我必须先使用命令:Add-Migration Identity,然后才能运行 Update-Database。谢谢!以上是关于如何在现有数据库中创建 ASP.Net Identity 表?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 asp.net 中创建 RESTful Web 服务?