Saltar al contenido

Confusión ASP.NET Identity DbContext

Estuvimos buscado por el mundo on line para así brindarte la solución a tu inquietud, en caso de alguna duda puedes dejar tu comentario y te contestaremos porque estamos para servirte.

Solución:

Usaría una sola clase de contexto heredada de IdentityDbContext. De esta manera, puede hacer que el contexto sea consciente de las relaciones entre sus clases y el IdentityUser y los roles de IdentityDbContext. Hay muy poca sobrecarga en IdentityDbContext, es básicamente un DbContext normal con dos DbSets. Uno para los usuarios y otro para los roles.

Hay mucha confusión sobre IdentityDbContext, una búsqueda rápida en Stackoverflow y encontrará estas preguntas:
“¿Por qué Asp.Net Identity IdentityDbContext es una caja negra?
¿Cómo puedo cambiar los nombres de las tablas cuando uso Visual Studio 2013 AspNet Identity?
Fusionar MyDbContext con IdentityDbContext “

Para responder a todas estas preguntas, debemos comprender que IdentityDbContext es solo una clase heredada de DbContext.
Echemos un vistazo a la fuente IdentityDbContext:

/// 
/// Base class for the Entity Framework database context used for identity.
/// 
/// The type of user objects.
/// The type of role objects.
/// The type of the primary key for users and roles.
/// The type of the user claim object.
/// The type of the user role object.
/// The type of the user login object.
/// The type of the role claim object.
/// The type of the user token object.
public abstract class IdentityDbContext : DbContext
    where TUser : IdentityUser
    where TRole : IdentityRole
    where TKey : IEquatable
    where TUserClaim : IdentityUserClaim
    where TUserRole : IdentityUserRole
    where TUserLogin : IdentityUserLogin
    where TRoleClaim : IdentityRoleClaim
    where TUserToken : IdentityUserToken

    /// 
    /// Initializes a new instance of .
    /// 
    /// The options to be used by a .
    public IdentityDbContext(DbContextOptions options) : base(options)
     

    /// 
    /// Initializes a new instance of the  class.
    /// 
    protected IdentityDbContext()
     

    /// 
    /// Gets or sets the  of Users.
    /// 
    public DbSet Users  get; set; 

    /// 
    /// Gets or sets the  of User claims.
    /// 
    public DbSet UserClaims  get; set; 

    /// 
    /// Gets or sets the  of User logins.
    /// 
    public DbSet UserLogins  get; set; 

    /// 
    /// Gets or sets the  of User roles.
    /// 
    public DbSet UserRoles  get; set; 

    /// 
    /// Gets or sets the  of User tokens.
    /// 
    public DbSet UserTokens  get; set; 

    /// 
    /// Gets or sets the  of roles.
    /// 
    public DbSet Roles  get; set; 

    /// 
    /// Gets or sets the  of role claims.
    /// 
    public DbSet RoleClaims  get; set; 

    /// 
    /// Configures the schema needed for the identity framework.
    /// 
    /// 
    /// The builder being used to construct the model for this context.
    /// 
    protected override void OnModelCreating(ModelBuilder builder)
    
        builder.Entity(b =>
        
            b.HasKey(u => u.Id);
            b.HasIndex(u => u.NormalizedUserName).HasName("UserNameIndex").IsUnique();
            b.HasIndex(u => u.NormalizedEmail).HasName("EmailIndex");
            b.ToTable("AspNetUsers");
            b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();

            b.Property(u => u.UserName).HasMaxLength(256);
            b.Property(u => u.NormalizedUserName).HasMaxLength(256);
            b.Property(u => u.Email).HasMaxLength(256);
            b.Property(u => u.NormalizedEmail).HasMaxLength(256);
            b.HasMany(u => u.Claims).WithOne().HasForeignKey(uc => uc.UserId).IsRequired();
            b.HasMany(u => u.Logins).WithOne().HasForeignKey(ul => ul.UserId).IsRequired();
            b.HasMany(u => u.Roles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
        );

        builder.Entity(b =>
        
            b.HasKey(r => r.Id);
            b.HasIndex(r => r.NormalizedName).HasName("RoleNameIndex");
            b.ToTable("AspNetRoles");
            b.Property(r => r.ConcurrencyStamp).IsConcurrencyToken();

            b.Property(u => u.Name).HasMaxLength(256);
            b.Property(u => u.NormalizedName).HasMaxLength(256);

            b.HasMany(r => r.Users).WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
            b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
        );

        builder.Entity(b => 
        
            b.HasKey(uc => uc.Id);
            b.ToTable("AspNetUserClaims");
        );

        builder.Entity(b => 
        
            b.HasKey(rc => rc.Id);
            b.ToTable("AspNetRoleClaims");
        );

        builder.Entity(b => 
        
            b.HasKey(r => new  r.UserId, r.RoleId );
            b.ToTable("AspNetUserRoles");
        );

        builder.Entity(b =>
        
            b.HasKey(l => new  l.LoginProvider, l.ProviderKey );
            b.ToTable("AspNetUserLogins");
        );

        builder.Entity(b => 
        
            b.HasKey(l => new  l.UserId, l.LoginProvider, l.Name );
            b.ToTable("AspNetUserTokens");
        );
    

Basado en el código fuente si queremos fusionar IdentityDbContext con nuestro DbContext tenemos dos opciones:

Primera opción:

Cree un DbContext que herede de IdentityDbContext y tenga acceso a las clases.

   public class ApplicationDbContext 
    : IdentityDbContext

    public ApplicationDbContext()
        : base("DefaultConnection")
    
    

    static ApplicationDbContext()
    
        Database.SetInitializer(new ApplicationDbInitializer());
    

    public static ApplicationDbContext Create()
    
        return new ApplicationDbContext();
    

    // Add additional items here as needed

Notas adicionales:

1) También podemos cambiar los nombres de las tablas predeterminadas de identidad de asp.net con la siguiente solución:

    public class ApplicationDbContext : IdentityDbContext
        
        public ApplicationDbContext(): base("DefaultConnection")
        
        

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity().ToTable("user");
            modelBuilder.Entity().ToTable("user");

            modelBuilder.Entity().ToTable("role");
            modelBuilder.Entity().ToTable("userrole");
            modelBuilder.Entity().ToTable("userclaim");
            modelBuilder.Entity().ToTable("userlogin");
        
    

2) Además, podemos extender cada clase y agregar cualquier propiedad a clases como ‘IdentityUser’, ‘IdentityRole’, …

    public class ApplicationRole : IdentityRole

    public ApplicationRole() 
    
        this.Id = Guid.NewGuid().ToString();
    

    public ApplicationRole(string name)
        : this()
    
        this.Name = name;
    

    // Add any custom Role properties/code here



// Must be expressed in terms of our custom types:
public class ApplicationDbContext 
    : IdentityDbContext

    public ApplicationDbContext()
        : base("DefaultConnection")
    
    

    static ApplicationDbContext()
    
        Database.SetInitializer(new ApplicationDbInitializer());
    

    public static ApplicationDbContext Create()
    
        return new ApplicationDbContext();
    

    // Add additional items here as needed

Para ahorrar tiempo, podemos utilizar la plantilla de proyecto extensible AspNet Identity 2.0 para ampliar todas las clases.

Segunda opción:(No recomendado)

En realidad, no tenemos que heredar de IdentityDbContext si escribimos todo el código nosotros mismos.
Entonces, básicamente, podemos heredar de DbContext e implementar nuestra versión personalizada de “OnModelCreating (ModelBuilder builder)” del código fuente de IdentityDbContext

Esta es una entrada tardía para la gente, pero a continuación se muestra mi implementación. También notará que eliminé la capacidad de cambiar el tipo predeterminado de CLAVES: los detalles sobre los cuales se pueden encontrar en los siguientes artículos:

  • Ampliación de modelos de identidad y uso de claves enteras en lugar de cadenas
  • Cambiar la clave principal para los usuarios en la identidad ASP.NET

NOTAS:

Cabe señalar que no puede utilizar Guid's para tu keys. Esto se debe a que debajo del capó son un Struct, y como tal, no tienen unboxing que permitiría su conversión de un genérico parámetro.

LAS CLASES SE VEN COMO:

public class ApplicationDbContext : IdentityDbContext

    #region 

    public ApplicationDbContext() : base(Settings.ConnectionString.Database.AdministrativeAccess)
    
    

    #endregion

    #region 

    //public DbSet Case  get; set; 

    #endregion

    #region 

    #region

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);

        //modelBuilder.Configurations.Add(new ResourceConfiguration());
        //modelBuilder.Configurations.Add(new OperationsToRolesConfiguration());
    

    #endregion

    #region

    public static ApplicationDbContext Create()
    
        return new ApplicationDbContext();
    

    #endregion

    #endregion


    public class ApplicationUser : IdentityUser
    
        #region 

        public ApplicationUser()
        
            Init();
        

        #endregion

        #region 

        [Required]
        [StringLength(250)]
        public string FirstName  get; set; 

        [Required]
        [StringLength(250)]
        public string LastName  get; set; 

        #endregion

        #region 

        #region private

        private void Init()
        
            Id = Guid.Empty.ToString();
        

        #endregion

        #region public

        public async Task GenerateUserIdentityAsync(UserManager manager)
        
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

            // Add custom user claims here

            return userIdentity;
        

        #endregion

        #endregion
    

    public class CustomUserStore : UserStore
    
        #region 

        public CustomUserStore(ApplicationDbContext context) : base(context)
        
        

        #endregion
    

    public class CustomUserRole : IdentityUserRole
    
    

    public class CustomUserLogin : IdentityUserLogin
    
    

    public class CustomUserClaim : IdentityUserClaim 
     
    

    public class CustomRoleStore : RoleStore
    
        #region 

        public CustomRoleStore(ApplicationDbContext context) : base(context)
        
         

        #endregion
    

    public class CustomRole : IdentityRole
    
        #region 

        public CustomRole()  
        public CustomRole(string name) 
         
            Name = name; 
        

        #endregion
    

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *