gpt4 book ai didi

sql-server - 使用 SQL 脚本创建 ASP.NET Identity 表

转载 作者:行者123 更新时间:2023-12-02 07:57:50 25 4
gpt4 key购买 nike

我正在尝试将 ASP.NET Identity 合并到当前使用 SQL 脚本创建数据库架构的新应用程序中。由于我们需要创建从其他表到用户表的外键约束,因此非常希望在相同的脚本中也创建 ASP.NET Identity 表。

我已经能够在 IdentityModels.cs 中创建的 ApplicationUser 类中扩展 IdentityUser 类 -

public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Sequence = 0;
LastActivity = DateTime.Now;
}

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int NumericId
{
get;
set;
}

[MaxLength(50), Required]
public string DisplayName
{
get;
set;
}

[MaxLength(50), Required]
public string Description
{
get;
set;
}

[IntegerValidator(MinValue = 0), Required]
public int Sequence
{
get;
set;
}

[MaxLength(50)]
public string ExternalRef
{
get;
set;
}

public DateTime? LoggedOn
{
get;
set;
}

public DateTime? LoggedOff
{
get;
set;
}

public DateTime LastActivity
{
get;
set;
}

public int FailedLoginAttempts
{
get;
set;
}

public DateTime? LockedOutUntil
{
get;
set;
}

public int LockOutCycles
{
get;
set;
}

public bool Approved
{
get;
set;
}
}

我已经使用脚本创建了表格-

CREATE TABLE [Users].[User] (
[Id] [nvarchar](128) NOT NULL
,[NumericId] [int] IDENTITY(1,1) NOT NULL
,[UserName] [nvarchar](50) NULL
,[PasswordHash] [nvarchar](max) NULL
,[SecurityStamp] [nvarchar](max) NULL
,[DisplayName] [nvarchar](50) NULL
,[Description] [nvarchar](50) NOT NULL
,[EmailAddress] [nvarchar](254) NOT NULL
,[Confirmed] [bit] NOT NULL
,[Sequence] [int] NOT NULL
,[ExternalRef] [nvarchar](50) NOT NULL
,[LoggedOn] [datetime] NULL
,[LoggedOff] [datetime] NULL
,[LastActivity] [datetime] NULL
,[FailedLoginAttempts] [int] NOT NULL
,[LockedOutUntil] [datetime] NULL
,[LockOutCycles] int NOT NULL
,[Approved] [bit] NOT NULL
,[Discriminator] [nvarchar](128) NOT NULL
,CONSTRAINT [PK_User] PRIMARY KEY NONCLUSTERED ([Id] ASC) WITH (
PAD_INDEX = OFF
,STATISTICS_NORECOMPUTE = OFF
,IGNORE_DUP_KEY = OFF
,ALLOW_ROW_LOCKS = ON
,ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
,CONSTRAINT [IX_User_NumericId] UNIQUE CLUSTERED ([NumericId] ASC) WITH (
PAD_INDEX = OFF
,STATISTICS_NORECOMPUTE = OFF
,IGNORE_DUP_KEY = OFF
,ALLOW_ROW_LOCKS = ON
,ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
,CONSTRAINT [IX_User_Name] UNIQUE NONCLUSTERED ([UserName] 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

ALTER TABLE [Users].[User] ADD CONSTRAINT [DF_User_Description] DEFAULT('')
FOR [Description]
GO

ALTER TABLE [Users].[User] ADD CONSTRAINT [DF_User_Sequence] DEFAULT((0))
FOR [Sequence]
GO

ALTER TABLE [Users].[User] ADD CONSTRAINT [DF_User_ExternalRef] DEFAULT('')
FOR [ExternalRef]
GO

ALTER TABLE [Users].[User] ADD CONSTRAINT [DF_User_FailedLoginAttempts] DEFAULT((0))
FOR [FailedLoginAttempts]
GO

ALTER TABLE [Users].[User] ADD CONSTRAINT [DF_User_LockOutCycles] DEFAULT((0))
FOR [LockOutCycles]
GO

CREATE NONCLUSTERED INDEX [IX_User_Sequence] ON [Users].[User] ([Sequence] ASC, [UserName] ASC)
WITH (
PAD_INDEX = OFF
,STATISTICS_NORECOMPUTE = OFF
,SORT_IN_TEMPDB = OFF
,IGNORE_DUP_KEY = OFF
,DROP_EXISTING = OFF
,ONLINE = OFF
,ALLOW_ROW_LOCKS = ON
,ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
GO

CREATE TABLE [Users].[UserClaim](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ClaimType] [nvarchar](max) NULL,
[ClaimValue] [nvarchar](max) NULL,
[UserId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Users.UserClaims] 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 [Users].[UserClaim] WITH CHECK ADD CONSTRAINT [FK_Users.UserClaims_Users.User_User_Id] FOREIGN KEY([UserId])
REFERENCES [Users].[User] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [Users].[UserClaim] CHECK CONSTRAINT [FK_Users.UserClaims_Users.User_User_Id]
GO

CREATE TABLE [Users].[UserLogin](
[UserId] [nvarchar](128) NOT NULL,
[LoginProvider] [nvarchar](128) NOT NULL,
[ProviderKey] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Users.UserLogins] PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[LoginProvider] ASC,
[ProviderKey] 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

ALTER TABLE [Users].[UserLogin] WITH CHECK ADD CONSTRAINT [FK_Users.UserLogins_Users.User_UserId] FOREIGN KEY([UserId])
REFERENCES [Users].[User] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [Users].[UserLogin] CHECK CONSTRAINT [FK_Users.UserLogins_Users.User_UserId]

CREATE TABLE [Users].[ApplicationRole](
[Id] [nvarchar](128) NOT NULL,
[Name] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_Users.ApplicationRole] 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]


CREATE TABLE [Users].[UserRole](
[UserId] [nvarchar](128) NOT NULL,
[RoleId] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Users.UserRole] 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

ALTER TABLE [Users].[UserRole] WITH CHECK ADD CONSTRAINT [FK_Users.UserRole_Users.ApplicationRole_RoleId] FOREIGN KEY([RoleId])
REFERENCES [Users].[ApplicationRole] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [Users].[UserRole] CHECK CONSTRAINT [FK_Users.UserRole_Users.ApplicationRole_RoleId]
GO

ALTER TABLE [Users].[UserRole] WITH CHECK ADD CONSTRAINT [FK_Users.UserRole_Users.User_UserId] FOREIGN KEY([UserId])
REFERENCES [Users].[User] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [Users].[UserRole] CHECK CONSTRAINT [FK_Users.UserRole_Users.User_UserId]
GO

CREATE TABLE [Users].[Department](
[Id] [int] IDENTITY(1, 1) NOT NULL
,[Name] [nvarchar](50) NOT NULL
,[Description] [nvarchar](50) NOT NULL
,[Sequence] [int] NOT NULL
CONSTRAINT [PK_Users.Department] 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

并使用 OnModelCreating 事件的覆盖将实体映射到表 -

public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>().ToTable("User", "Users");

modelBuilder.Entity<IdentityUser>().Property(iu => iu.Id).HasColumnName("Id");
modelBuilder.Entity<IdentityUser>().Property(iu => iu.UserName).HasColumnName("UserName");
modelBuilder.Entity<IdentityUser>().Property(iu => iu.Email).HasColumnName("EmailAddress").HasMaxLength(254).IsRequired();
modelBuilder.Entity<IdentityUser>().Property(iu => iu.PasswordHash).HasColumnName("PasswordHash");
modelBuilder.Entity<IdentityUser>().Property(iu => iu.SecurityStamp).HasColumnName("SecurityStamp");
modelBuilder.Entity<IdentityUser>().Property(iu => iu.IsConfirmed).HasColumnName("Confirmed");

modelBuilder.Entity<ApplicationUser>().HasKey(au => au.Id).ToTable("User", "Users"); //Specify our our own table names instead of the defaults

modelBuilder.Entity<ApplicationUser>().Property(au => au.Id).HasColumnName("Id");
modelBuilder.Entity<ApplicationUser>().Property(au => au.NumericId).HasColumnName("NumericId");
modelBuilder.Entity<ApplicationUser>().Property(au => au.UserName).HasMaxLength(50).HasColumnName("UserName");
modelBuilder.Entity<ApplicationUser>().Property(au => au.PasswordHash).HasColumnName("PasswordHash");
modelBuilder.Entity<ApplicationUser>().Property(au => au.SecurityStamp).HasColumnName("SecurityStamp");
modelBuilder.Entity<ApplicationUser>().Property(au => au.DisplayName).HasColumnName("DisplayName");
modelBuilder.Entity<ApplicationUser>().Property(au => au.Description).HasColumnName("Description");
modelBuilder.Entity<ApplicationUser>().Property(au => au.Sequence).HasColumnName("Sequence");
modelBuilder.Entity<ApplicationUser>().Property(au => au.ExternalRef).HasColumnName("ExternalRef");
modelBuilder.Entity<ApplicationUser>().Property(au => au.LoggedOn).HasColumnName("LoggedOn");
modelBuilder.Entity<ApplicationUser>().Property(au => au.LoggedOff).HasColumnName("LoggedOff");
modelBuilder.Entity<ApplicationUser>().Property(au => au.LastActivity).HasColumnName("LastActivity");
modelBuilder.Entity<ApplicationUser>().Property(au => au.FailedLoginAttempts).IsOptional().HasColumnName("FailedLoginAttempts");
modelBuilder.Entity<ApplicationUser>().Property(au => au.LockedOutUntil).IsOptional().HasColumnName("LockedOutUntil");
modelBuilder.Entity<ApplicationUser>().Property(au => au.LockOutCycles).IsOptional().HasColumnName("LockOutCycles");
modelBuilder.Entity<ApplicationUser>().Property(au => au.Approved).HasColumnName("Approved");

modelBuilder.Entity<IdentityRole>().HasKey(ir => ir.Id).ToTable("ApplicationRole", "Users");

modelBuilder.Entity<IdentityRole>().Property(ir => ir.Id).HasColumnName("Id");
modelBuilder.Entity<IdentityRole>().Property(ir => ir.Name).HasColumnName("Name");

modelBuilder.Entity<IdentityUserClaim>().HasKey(iuc => iuc.Id).ToTable("UserClaim", "Users");

modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.Id).HasColumnName("Id");
modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.ClaimType).HasColumnName("ClaimType");
modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.ClaimValue).HasColumnName("ClaimValue");
modelBuilder.Entity<IdentityUserClaim>().Property(iuc => iuc.UserId).HasColumnName("UserId");

modelBuilder.Entity<IdentityUserLogin>().HasKey(iul => new { iul.UserId, iul.LoginProvider, iul.ProviderKey }).ToTable("UserLogin", "Users"); //Used for third party OAuth providers

modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.UserId).HasColumnName("UserId");
modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.LoginProvider).HasColumnName("LoginProvider");
modelBuilder.Entity<IdentityUserLogin>().Property(iul => iul.ProviderKey).HasColumnName("ProviderKey");

modelBuilder.Entity<IdentityUserRole>().HasKey(iur => new { iur.UserId, iur.RoleId }).ToTable("UserRole", "Users");

modelBuilder.Entity<IdentityUserRole>().Property(ur => ur.UserId).HasColumnName("UserId");
modelBuilder.Entity<IdentityUserRole>().Property(ur => ur.RoleId).HasColumnName("RoleId");
}

这对于注册来说效果很好,并且确实在注册后登录,但是在此之后任何尝试登录都会导致 -

Exception Details: System.Data.SqlClient.SqlException:

Invalid column name 'IdentityUser_Id'.

Invalid column name 'IdentityUser_Id'.

Invalid column name 'Id'. Invalid column name 'IdentityRole_Id'.

Invalid column name 'IdentityUser_Id'.

Source Error:

Line 337: {

Line 338:
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

Line 339:
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

Line 340:
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, identity);

Line 341: }

我认为这是 ApplicationUser 和 IdentityUserRole 实体之间的外键问题 - 这些实体存在于数据库中,但未在 Fluent API 映射中定义。 IdentityUser 是复杂类型的事实似乎导致 EF 假设这些列基于生成的查询附加到 IdentityUserRole 表(名为“[User].[UserRole]”) -

exec sp_executesql N'SELECT 
[Extent1].[Id] AS [Id],
[Extent1].[UserId] AS [UserId],
[Extent1].[RoleId] AS [RoleId],
[Extent1].[IdentityRole_Id] AS [IdentityRole_Id],
[Extent1].[IdentityUser_Id] AS [IdentityUser_Id]
FROM [Users].[UserRole] AS [Extent1]
WHERE ([Extent1].[IdentityUser_Id] IS NOT NULL) AND ([Extent1].[IdentityUser_Id] =
@EntityKeyValue1)',N'@EntityKeyValue1 nvarchar(128)',
@EntityKeyValue1=N'2e16b5b5-6604-4f2c-9fbb-7cc3f5c9d4f3'
go

如何在 Fluent API 中配置外键,从 ApplicationUser/IdentityUser 和 IdentityRole 类指向“[Users].[User]”表,或从 IdentityUserRole 类指向用户并角色实体还是表? SQL 中已存在外键。

最佳答案

因此,默认情况下,新的 1.1-alpha1 位将具有与以下内容接近的内容。这可能就是您正在寻找的有关外键的内容。注意:这与 1.0 略有不同,因为导航属性进行了一些更改以启用指定主键类型的功能:

我们正在尝试解决一些 EF 迁移/可扩展性问题,因此希望使用 Identity 1.1-alpha1 和即将推出的 6.0.2/6.1 EF 版本会使事情变得更容易,但我不确定更新的 EF 包是否有效尚未在 myget 上提供。

    var user = modelBuilder.Entity<TUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName).IsRequired();

modelBuilder.Entity<TUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles");

modelBuilder.Entity<TUserLogin>()
.HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey})
.ToTable("AspNetUserLogins");

modelBuilder.Entity<TUserClaim>()
.ToTable("AspNetUserClaims");

var role = modelBuilder.Entity<TRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name).IsRequired();
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);

关于sql-server - 使用 SQL 脚本创建 ASP.NET Identity 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19932993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com