O ASP.NET Identity possui um padrão de nomenclatura para suas tabelas e campos, muitas vezes é necessário customizar este padrão para atender as necessidades da aplicação, confira como é simples realizar esta tarefa.
Como apresentado aqui algumas vezes, o ASP.NET Identity é um componente muito completo e simples de customizar, ele é escrito baseado no conceito Code-First e sua arquitetura é bem aberta possibilitando a customização de funcionalidades, comportamentos e até mesmo fonte de dados.
As tabelas que o ASP.NET Identity cria automaticamente segue o mesmo processo de qualquer desenvolvimento Code-First, permitindo que o desenvolvedor mapeie na configuração do DbContext toda a modelagem da base que será criada.
Vamos abordar de forma muito simples e pontual como realizar este processo partindo do pré-suposto que sua aplicação foi criada com base no template de aplicação ASP.NET MVC já com o ASP.NET Identity configurado. Independente deste fato, o que é realmente necessário fazer é editar o contexto do ASP.NET Identity.
Uma dica válida para qualquer situação é manter sempre o contexto do ASP.NET Identity separado do contexto da aplicação.
Iremos trabalhar também com a hipótese de customização do IdentityUser através de sua classe derivada ApplicationUser. Vamos ao código.
public class ApplicationUser : IdentityUser
{
public string Apelido { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Usuarios")
.Property(p => p.Id)
.HasColumnName("UsuarioId");
modelBuilder.Entity<ApplicationUser>()
.ToTable("Usuarios")
.Property(p => p.Id)
.HasColumnName("UsuarioId");
modelBuilder.Entity<IdentityUserRole>()
.ToTable("UsuarioPapel");
modelBuilder.Entity<IdentityUserLogin>()
.ToTable("Logins");
modelBuilder.Entity<IdentityUserClaim>()
.ToTable("Claims");
modelBuilder.Entity<IdentityRole>()
.ToTable("Papeis");
}
}
Na classe ApplicationUser realizamos uma pequena customização adicionando um novo campo (Apelido), apenas para enfatizar a situação.
Na classe ApplicationDbContext repare que ela herda de IdentityDbContext, que é a real classe de contexto do ASP.NET Identity onde ela internamente herda de DbContext.
A ideia de existir a classe ApplicationDbContext é justamente fornecer um contexto para customização, uma vez que a classe IdentityDbContext faz parte dos assemblies do ASP.NET Identity e não é possível ser alterada.
Baseado no conceito da herança o que basicamente fizemos foi sobrescrever o método OnModelCreating da classe base para alterarmos os padrões de nomenclatura. Utilizamos Fluent API para realizar esse mapeamento trocando os nomes das tabelas e campos.
Essa troca não impacta no funcionamento interno do ASP.NET Identity, pois as classes internas permanecem intactas, apenas o mapeamento do modelo objeto / relacional foi modificado e a aplicação irá seguir o que a modelagem manda.
modelBuilder.Entity<IdentityUser>()
.ToTable("Usuarios")
.Property(p => p.Id)
.HasColumnName("UsuarioId");
modelBuilder.Entity<ApplicationUser>()
.ToTable("Usuarios")
.Property(p => p.Id)
.HasColumnName("UsuarioId");
Repare que as duas classes (IdentityUser, ApplicationUser) foram mapeadas para mesma tabela, pois só assim seria possível mapear a classe de usuários e ao mesmo tempo aplicar as customizações, no final tudo vira uma única tabela com informações de ambas as classes.
Detalhes adicionais
- É possível utilizar todos os recursos do Fluent API nessa abordagem, sendo possível modificar tipo dos campos, inserir índices, criar novos relacionamentos, mapear novas tabelas e etc.
- É possível realizar todo este mapeamento em uma outra classe e configurar esta classe no contexto (assim como fazemos com as nossas entidades no Fluent API).
Simples?
Agora é possível incorporar o ASP.NET Identity ao seu modelo já existente de base de usuários, a única premissa é que todas as tabelas e campos do ASP.NET Identity sejam representados (mapeados) de alguma forma no banco de dados existente.
Vamos continuar a enriquecer este artigo participando nos comentários abaixo com dúvidas, complementos e feedbacks.
Referências
Este artigo foi escrito durante minha participação na Campus Party 2015 #CPBR8