Why is Asp.Net Identity IdentityDbContext a Black-Box?

前端 未结 4 421
星月不相逢
星月不相逢 2020-11-30 03:08

There is a lot of confusion it seems around IdentityDbContext.

If we create two Database Contexts in our application, one for Identity and one for our c

4条回答
  •  误落风尘
    2020-11-30 03:55

    There is certainly lots of confusion around IdentityDbContext, a quick search around SO and you will find lots of questions about this topic.
    ASP.NET Identity DbContext confusion
    How can I change the table names when using Visual Studio 2013 AspNet Identity?
    Merge MyDbContext with IdentityDbContext

    The answer to all of these questions we need to first understand how IdentityDbContext works. To clarify things, we should take into consideration that IdentityDbContext is just a class inherited from DbContext and not a black box!
    Let's take a look at IdentityDbContext source:

    /// 
    /// 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");
            });
        }
    }
    

    Based on the source code all you have to do is create a DbContext which inherits from IdentityDbContext and have access to the classes.

    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
    }
    

    If you want to further extend the classes have a look at AspNet Identity 2.0 Extensible Project Template

提交回复
热议问题