58

我正在查看新的 ASP.NET Identity 类的接口以及它使用 Entity Framework Code First 创建的数据库。我正在使用 Visual Studio 2013 RC。

乍一看,数据库模式看起来相当正常:

在此处输入图像描述

但是所有的键都是 NVARCHAR(128)

出于某种疯狂的原因AspNetUserSecrets.Id,PK 看起来可能指向AspNetUsers表格中的多个记录。这是否意味着多个AspNetUsers必须共享相同的密码?

当我查看查看您被迫实现的接口时,这些都是字符串...

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; }
}

所以我开始接受这样一个事实,即我可能必须使用字符串来实现 PK 和 FK 关系。

但我真的很想知道为什么它是这样建造的......?

编辑:时间已经过去,现在有关于如何扩展 asp.net 身份以使用 int(或 guid)字段的文章:

http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity

4

3 回答 3

35

目的是允许任意 id 类型(即int, guid, string),但也避免 id 属性出现序列化/转换问题。

所以你可以随意定义你的键,只需要实现接口方法

public class MyUser : IUser {
  public int Id { get; set; }
  string IUser.Id { get { return Id.ToString(); } }
}
于 2013-10-09T21:54:32.827 回答
19

补充郝说的:

  1. Identity 运行时更喜欢用户 ID 的字符串,因为我们不想从事找出用户 ID 的正确序列化的业务(出于同样的原因,我们也将字符串用于声明),例如所有(或大部分)身份接口将用户 ID 称为字符串。
  2. 自定义持久层的人,例如实体类型,可以选择他们想要的任何类型的键,但是他们自己为我们提供了键的字符串表示。
  3. 默认情况下,我们为每个新用户使用 GUID 的字符串表示,但这只是因为它为我们提供了一种非常简单的方法来自动生成唯一 ID。
于 2014-06-10T22:48:03.677 回答
2

使用 ASP.NET Core,您可以通过一种非常简单的方式为 Identity 模型指定所需的数据类型。

第一步,将身份类从<string>重写为<data type you want>

public class ApplicationUser : IdentityUser<Guid>
{
}

public class ApplicationRole : IdentityRole<Guid>
{
}

使用您的类和您想要的数据类型声明您的数据库上下文:

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);
        }
    }

在您的启动类中,使用您的模型声明身份服务并声明您想要的主键数据类型:

services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
            .AddDefaultTokenProviders();

在 ASP.NET 标识表中,主键仍将位于 NVARCHAR 中,但在您的应用程序中,它将是您想要的数据类型。您可以在控制器中检查:

    [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();
    }
于 2016-10-17T06:32:49.297 回答