tables - ¿Por qué las interfaces de Identidad ASP.NET usan cadenas para claves primarias y externas?
asp.net membership (3)
Estoy mirando las interfaces en las nuevas clases de Identidad ASP.NET y la base de datos que crea usando Entity Framework Code First. Estoy usando el Visual Studio 2013 RC.
A primera vista, el esquema de la base de datos se ve razonablemente normal:
Pero todas las claves son NVARCHAR (128)
Y por alguna razón loca AspNetUserSecrets.Id
es un PK que parece que podría apuntar a más de un registro en la tabla AspNetUsers
. ¿Significa esto que múltiples AspNetUsers
tendrán que compartir la misma contraseña?
Cuando miro las interfaces que estás obligado a implementar, estas son todas las cadenas ...
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; }
}
Así que estoy llegando a un acuerdo con el hecho de que podría tener que implementar esto usando cadenas para las relaciones PK y FK.
Pero realmente me gustaría saber POR QUÉ está construido así ...?
EDITAR: Ha pasado el tiempo y ahora hay artículos sobre cómo extender la identidad asp.net para usar los campos int (o guid):
http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
Agregando a lo que Hao dijo:
- El tiempo de ejecución de Identity prefiere cadenas para el ID de usuario porque no queremos estar en el negocio de descifrar la serialización adecuada de los ID de usuario (también utilizamos cadenas para reclamos por la misma razón), por ejemplo, todos (o la mayoría) de las interfaces de Identidad se refieren a la identificación del usuario como una cadena.
- Las personas que personalizan la capa de persistencia, por ejemplo, los tipos de entidades, pueden elegir el tipo que deseen para las claves, pero luego son ellas las que nos proporcionan una representación de cadena de las claves.
- De forma predeterminada, utilizamos la representación de cadena de GUID para cada nuevo usuario, pero eso es solo porque proporciona una manera muy fácil para que generemos automáticamente ID únicos.
Con ASP.NET Core, tiene una manera muy simple de especificar el tipo de datos que desea para los modelos de Identity.
Primer paso, anule las clases de identidad de <cadena> a <tipo de datos que desea> :
public class ApplicationUser : IdentityUser<Guid>
{
}
public class ApplicationRole : IdentityRole<Guid>
{
}
Declare el contexto de su base de datos, usando sus clases y el tipo de datos que desea:
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);
}
}
Y en su clase de inicio, declare el servicio de identidad utilizando sus modelos y declare el tipo de datos que desea para las claves principales:
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext, Guid>()
.AddDefaultTokenProviders();
En las tablas de identidad de ASP.NET, las claves primarias seguirán estando en NVARCHAR, pero en su aplicación será el tipo de datos que desee. Puedes verificar esto en un controlador:
[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();
}
La intención era permitir tanto los tipos de identificación arbitrarios (es decir, int
, guid
, string
), pero también evitar tener problemas de serialización / conversión para la propiedad id.
Así que puedes definir tus claves como quieras y solo implementar el método de interfaz
public class MyUser : IUser {
public int Id { get; set; }
string IUser.Id { get { return Id.ToString(); } }
}