如何在SQL Server上更改ASP.Net Identity 2以创建newSequentialId主键?
我有一个ASP.NET Identity 2实现(没有用户数据,只有基表),用户ID类型为UNIQUEIDENTIFIER 这个应用程序首先是一个代码,我使用的是EF6 以下是DDL:如何在SQL Server上更改ASP.Net Identity 2以创建newSequentialId主键?,asp.net,asp.net-mvc,asp.net-mvc-5,asp.net-identity,asp.net-identity-2,Asp.net,Asp.net Mvc,Asp.net Mvc 5,Asp.net Identity,Asp.net Identity 2,我有一个ASP.NET Identity 2实现(没有用户数据,只有基表),用户ID类型为UNIQUEIDENTIFIER 这个应用程序首先是一个代码,我使用的是EF6 以下是DDL: CREATE TABLE [dbo].[AspNetUsers] ( [Id] UNIQUEIDENTIFIER NOT NULL, [FirstName] NVARCHAR (MAX) NULL, [LastName]
CREATE TABLE [dbo].[AspNetUsers] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[FirstName] NVARCHAR (MAX) NULL,
[LastName] NVARCHAR (MAX) 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,
[SubjectId] INT DEFAULT ((0)) NOT NULL,
[SubjectIds] VARCHAR (50) NULL,
[OrganizationId] INT DEFAULT ((0)) NOT NULL,
[OrganizationIds] VARCHAR (50) NULL,
[RoleId] INT DEFAULT ((0)) NOT NULL,
CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex]
ON [dbo].[AspNetUsers]([UserName] ASC);
我知道创建的普通GUID是一个普通GUID
有人能告诉我如何创建一个newSequential GUID吗
请注意
我正在寻找正确的方法来实现这一点,特别是使用ASP.Net Identity 2。特别是我想知道是否需要对Identity 2 UserManager等进行任何更改。我终于能够构建并运行该项目。使用Fluent API创建后,将
newsequentialid()
分配给ID字段:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().Property(t => t.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<CustomUserRole>().HasKey(x => new
{
x.RoleId,
x.UserId
});
modelBuilder.Entity<CustomUserLogin>().HasKey(x => new
{
x.UserId,
x.ProviderKey,
x.LoginProvider
});
}
必须更改其他实体类型:
public class ApplicationUser : IdentityUser<Guid, CustomUserLogin, CustomUserRole,
CustomUserClaim>
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override Guid Id { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, Guid> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class CustomUserRole : IdentityUserRole<Guid> { }
public class CustomUserClaim : IdentityUserClaim<Guid> { }
public class CustomUserLogin : IdentityUserLogin<Guid> { }
public class CustomRole : IdentityRole<Guid, CustomUserRole>
{
public CustomRole() { }
public CustomRole(string name) { Name = name; }
}
public class CustomUserStore : UserStore<ApplicationUser, CustomRole, Guid,
CustomUserLogin, CustomUserRole, CustomUserClaim>
{
public CustomUserStore(ApplicationDbContext context)
: base(context)
{
}
}
public class CustomRoleStore : RoleStore<CustomRole, Guid, CustomUserRole>
{
public CustomRoleStore(ApplicationDbContext context)
: base(context)
{
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole,
Guid, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
替换userguid
而不是我看到的userId
我不得不在这里使用ToString()
:
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userGuidId.ToString())
在Account Controller中,我似乎只进行了更改
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code)
{
Guid GuidUserId = new Guid(userId);
if (userId == null || code == null)
{
return View("Error");
}
var result = await UserManager.ConfirmEmailAsync(GuidUserId, code);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
[AllowAnonymous]
公共异步任务确认邮件(字符串用户ID、字符串代码)
{
Guid GuidUserId=新的Guid(用户ID);
if(userId==null | | code==null)
{
返回视图(“错误”);
}
var result=await UserManager.confirmemailsync(GuidUserId,代码);
返回视图(result.successed?“确认邮件”:“错误”);
}
首先创建基于“IdentityUser”的类的非通用版本
public class AppUserClaim : IdentityUserClaim<Guid> { }
public class AppUserLogin : IdentityUserLogin<Guid> { }
public class AppUserRole : IdentityUserRole<Guid> { }
。。。最后是IdentityDbContext
public class AppIdentityContext : IdentityDbContext<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
public AppIdentityContext()
: base("name=AspNetIdentity")
{
}
}
在构造函数中,我们使用UuidCreateSequential
函数创建一个新ID,并通过ID
属性返回该ID。我想将数据库中的Id
列设置为使用newsequentialid()
作为默认值,并使用它而不是DllImport
,但我还没有解决这个问题
要在控制器操作中使用:
public async Task<ActionResult> ActionName()
{
AppIdentityContext dbContext = new AppIdentityContext();
AppUserStore store = new AppUserStore(dbContext);
AppUserManager manager = new AppUserManager(store);
AppUser user = new AppUser { UserName = "<name>", Email = "<email>" };
await manager.CreateAsync(user);
return this.View();
}
public异步任务ActionName()
{
AppIdentityContext dbContext=新的AppIdentityContext();
AppUserStore=新的AppUserStore(dbContext);
AppUserManager=新的AppUserManager(商店);
AppUser=新的AppUser{UserName=”“,Email=“”};
wait manager.CreateAsync(用户);
返回这个.View();
}
需要注意的几点:
AspNetUsers
中的Id
列为nvarchar
,则需要将以下列更改为唯一标识符
:
public class AppUser : IdentityUser<Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
[DllImport("rpcrt4.dll", SetLastError = true)]
private static extern int UuidCreateSequential(out Guid guid);
private Guid _id;
public AppUser()
{
UuidCreateSequential(out _id);
}
/// <summary>
/// User ID (Primary Key)
/// </summary>
public override Guid Id
{
get { return _id; }
set { _id = value; }
}
}
- AspNetUsers.Id
- AspNetRoles.Id
- AspNetUserRoles.UserId
- AspNetUserRoles.RoleId
IIdentity
接口上使用GetUserId
扩展方法,即this.User.Identity.GetUserId()
,将返回一个字符串,因此在将返回值转换为字符串时必须使用以下方法:
新Guid(this.User.Identity.GetUserId())
此方法有一个通用版本,但在其下面使用了Convert.ChangeType
,它需要在实现IConvertable
中传递值,而Guid
不需要
- 实体框架
- Microsoft.AspNet.Identity.Core
- Microsoft.AspNet.Identity.EntityFramework
App\u Start
文件夹中名为Identity.cs
的文件中
注意:排除控制器操作示例。这将在步骤6中完成web.config
AspNetIdentity的新连接字符串添加到web.config
家庭控制器上的索引操作中,并更换
和
部件
AspNetIdentity
的新空数据库添加到SQL Server如果您使用的ASP.NET MVC模板选择了“个人用户帐户身份验证”选项,则会出现一些必须修复的错误。这些主要围绕着将对
IdentityUser*
类的引用更改为新的基于AppUser*
的类,并替换对User.Identity.GetUserId()的调用
使用我原始答案中步骤#2中提供的代码示例。这是我使Guid类型的角色和用户Id字段具有默认值或绑定的newsequentialid()
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<ApplicationRole>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().Property(t=>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity().Property(t=>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
添加迁移初始值
更新数据库
警告:这将从您的数据库中删除所有角色用户这其中的哪一部分使其具有顺序?@Stilga
public class AppUserClaim : IdentityUserClaim<Guid> { }
public class AppUserLogin : IdentityUserLogin<Guid> { }
public class AppUserRole : IdentityUserRole<Guid> { }
public class AppRole : IdentityRole<Guid, AppUserRole>
{
}
public class AppUserStore : UserStore<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
public AppUserStore(DbContext context)
: base(context)
{
}
}
public class AppUserManager : UserManager<AppUser, Guid>
{
public AppUserManager(IUserStore<AppUser, Guid> store)
: base(store)
{
}
}
public class AppIdentityContext : IdentityDbContext<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
public AppIdentityContext()
: base("name=AspNetIdentity")
{
}
}
public class AppUser : IdentityUser<Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
[DllImport("rpcrt4.dll", SetLastError = true)]
private static extern int UuidCreateSequential(out Guid guid);
private Guid _id;
public AppUser()
{
UuidCreateSequential(out _id);
}
/// <summary>
/// User ID (Primary Key)
/// </summary>
public override Guid Id
{
get { return _id; }
set { _id = value; }
}
}
public async Task<ActionResult> ActionName()
{
AppIdentityContext dbContext = new AppIdentityContext();
AppUserStore store = new AppUserStore(dbContext);
AppUserManager manager = new AppUserManager(store);
AppUser user = new AppUser { UserName = "<name>", Email = "<email>" };
await manager.CreateAsync(user);
return this.View();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<ApplicationRole>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}