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