为什么ASP.NET Identity接口为主键和外键使用string?
我正在查看新的ASP.NET Identity类的接口以及使用Entity Framework Code First创build的数据库。 我正在使用Visual Studio 2013 RC。
乍一看,数据库模式看起来相当正常:
但是所有的键都是NVARCHAR(128)
而出于一些疯狂的原因AspNetUserSecrets.Id
是一个PK,看起来像它可以指向AspNetUsers
表中的多个logging。 这是否意味着多个AspNetUsers
必须共享相同的密码?
当我看着你被迫执行的接口,这些都是string…
public class User : IUser { public string Id { get; set; } public string UserName { get; set; } } public class UserSecret : IUserSecret { public string UserName { get; set; } public string Secret { get; set; } } public class UserRole : IUserRole { public string UserId { get; set; } public string RoleId { get; set; } } public class UserClaim : IUserClaim { public string UserId { get; set; } public string ClaimType { get; set; } public string ClaimValue { get; set; } } public class UserManagement : IUserManagement { public string UserId { get; set; } public bool DisableSignIn { get; set; } public DateTime LastSignInTimeUtc { get; set; } } public class Tokens : IToken { public string Id { get; set; } public string Value { get; set; } public DateTime ValidUntilUtc { get; set; } } public class UserLogin : IUserLogin { public string UserId { get; set; } public string LoginProvider { get; set; } public string ProviderKey { get; set; } } public class Role : IRole { public string Id { get; set; } public string Name { get; set; } }
所以我来说,我可能不得不使用stringPK和FK关系实现这一点。
但我真的很想知道为什么它是这样构build的?
编辑:时间已经过去,现在有关于如何扩展asp.net标识使用int(或guid)字段的文章:
http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
目的是允许任意idtypes(即int
, guid
, string
),但也避免序列化/铸造问题的id属性。
所以你可以定义你的密钥,只要你喜欢,只需实现接口方法
public class MyUser : IUser { public int Id { get; set; } string IUser.Id { get { return Id.ToString(); } } }
再加上郝的话:
- Identity运行时优先select用户ID的string,因为我们不希望进行用户ID的正确序列化(因为同样的原因我们使用string),例如所有(或大部分)身份接口将用户ID称为string。
- 定制持久层的人,例如实体types,可以select他们想要的任何types的键,但是他们自己提供了一个string表示键。
- 默认情况下,我们为每个新用户使用GUID的string表示forms,但这仅仅是因为它为我们提供了一种自动生成唯一ID的非常简单的方法。
使用ASP.NET Core,您可以使用一种非常简单的方法来指定Identity的模型所需的数据types。
第一步,重写从<string>到<data type >所需的身份类别:
public class ApplicationUser : IdentityUser<Guid> { } public class ApplicationRole : IdentityRole<Guid> { }
声明你的数据库上下文,使用你的类和你想要的数据types:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Customize the ASP.NET Identity model and override the defaults if needed. // For example, you can rename the ASP.NET Identity table names and more. // Add your customizations after calling base.OnModelCreating(builder); } }
在您的启动类中,使用您的模型声明身份服务,并为主键声明所需的数据types:
services.AddIdentity<ApplicationUser, ApplicationRole>() .AddEntityFrameworkStores<ApplicationDbContext, Guid>() .AddDefaultTokenProviders();
在ASP.NET身份表中,主键仍将位于NVARCHAR中,但在您的应用程序中将是您所需的数据types。 你可以在控制器中检查这个:
[HttpGet] public async Task<IActionResult> Test() { ApplicationUser user = await _userManager.GetUserAsync(HttpContext.User); Guid userId = user.Id; // No cast from string, it's a Guid data type throw new NotImplementedException(); }