Подтвердить что ты не робот

Почему интерфейсы ASP.NET Identity используют строки для первичных и внешних ключей?

Я просматриваю интерфейсы на новых классах ASP.NET Identity и базу данных, которую он создает, используя Entity Framework Code First. Я использую Visual Studio 2013 RC.

На первый взгляд схема базы данных выглядит достаточно нормально:

enter image description here

Но все ключи: NVARCHAR (128)

И по какой-то сумасшедшей причине AspNetUserSecrets.Id - это ПК, который выглядит так, как будто он может указывать на несколько записей в таблице 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.

Но мне очень хотелось бы знать, ПОЧЕМУ он построен так...?

EDIT: прошло время, и теперь есть статьи о том, как расширить идентификатор asp.net для использования полей int (или guid):

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

4b9b3361

Ответ 1

Цель заключалась в том, чтобы разрешить как произвольные типы идентификаторов (т.е. int, guid, string), так и избежать проблем с сериализацией/литьем для свойства id.

Итак, вы можете определить свои ключи, как вам нравится, и просто реализовать метод интерфейса

public class MyUser : IUser {
  public int Id { get; set; }
  string IUser.Id { get { return Id.ToString(); } }
}

Ответ 2

Добавление к тому, что сказал Хао:

  • Сценарий Identity предпочитает строки для идентификатора пользователя, потому что мы не хотим заниматься правильной сериализацией идентификаторов пользователей (мы используем строки для претензий по той же причине), например. все (или большинство) интерфейсов Identity относятся к идентификатору пользователя в виде строки.
  • Люди, которые настраивают уровень сохранения, например. типы сущностей, могут выбирать любой тип, который они хотят для ключей, но затем они сами предоставляют нам строковое представление ключей.
  • По умолчанию мы используем строковое представление GUID для каждого нового пользователя, но это только потому, что он обеспечивает очень простой способ автоматического создания уникальных идентификаторов.

Ответ 3

С ASP.NET Core у вас есть очень простой способ указать тип данных, который вы хотите использовать для моделей Identity.

Первый шаг, переопределить классы идентичности из <string> to < тип данных, который вы хотите > :

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 a Guid data type
        throw new NotImplementedException();
    }