ASP.NET身份DbContext混淆
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET身份DbContext混淆相关的知识,希望对你有一定的参考价值。
默认的MVC 5 App附带了IdentityModels.cs中的这段代码 - 这段代码用于默认模板的所有ASP.NET Identity操作:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
public ApplicationDbContext()
: base("DefaultConnection")
如果我使用带有Entity Framework的视图构建一个新控制器并在对话框中创建一个“新数据上下文...”,我会为我生成这个:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebApplication1.Models
public class AllTheOtherStuffDbContext : DbContext
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies get; set;
如果我使用EF构建另一个控制器+视图,例如对于一个Animal模型,这个新行将在public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies get; set;
下自动生成 - 如下所示:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebApplication1.Models
public class AllTheOtherStuffDbContext : DbContext
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to drop and regenerate your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies get; set;
public System.Data.Entity.DbSet<WebApplication1.Models.Animal> Animals get; set;
ApplicationDbContext
(对于所有ASP.NET标识的东西)继承自IdentityDbContext
,DbContext
继承自AllOtherStuffDbContext
。 DbContext
(我自己的东西)继承自ApplicationDbContext
。
所以我的问题是:
我应该为所有其他自己的模型使用这两个中的哪一个(AllOtherStuffDbContext
和ApplicationDbContext
)?或者我应该使用默认的自动生成的DbContext
,因为它不应该是使用它的问题,因为它派生自基类DbContext
,还是会有一些开销?你应该在你的应用程序中只为你的所有模型使用一个ApplicationDbContext
对象(我已经在某处读过)所以我甚至不应该考虑在一个应用程序中同时使用AllOtherStuffDbContext
和Why is Asp.Net Identity IdentityDbContext a Black-Box??或者使用ASP.NET身份的MVC 5中的最佳实践是什么?
我会使用一个继承自IdentityDbContext的Context类。通过这种方式,您可以让上下文了解您的类与IdentityUser和IdentityDbContext的角色之间的任何关系。 IdentityDbContext中的开销非常小,它基本上是一个带有两个DbSet的常规DbContext。一个用户,一个用于角色。
IdentityDbContext有很多混淆,在Stackoverflow中快速搜索,你会发现这些问题: “How can I change the table names when using Visual Studio 2013 AspNet Identity? Merge MyDbContext with IdentityDbContext IdentityDbContext source”
要回答所有这些问题,我们需要了解IdentityDbContext只是一个继承自DbContext的类。
我们来看看/// <summary>
/// Base class for the Entity Framework database context used for identity.
/// </summary>
/// <typeparam name="TUser">The type of user objects.</typeparam>
/// <typeparam name="TRole">The type of role objects.</typeparam>
/// <typeparam name="TKey">The type of the primary key for users and roles.</typeparam>
/// <typeparam name="TUserClaim">The type of the user claim object.</typeparam>
/// <typeparam name="TUserRole">The type of the user role object.</typeparam>
/// <typeparam name="TUserLogin">The type of the user login object.</typeparam>
/// <typeparam name="TRoleClaim">The type of the role claim object.</typeparam>
/// <typeparam name="TUserToken">The type of the user token object.</typeparam>
public abstract class IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : DbContext
where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
/// <summary>
/// Initializes a new instance of <see cref="IdentityDbContext"/>.
/// </summary>
/// <param name="options">The options to be used by a <see cref="DbContext"/>.</param>
public IdentityDbContext(DbContextOptions options) : base(options)
/// <summary>
/// Initializes a new instance of the <see cref="IdentityDbContext" /> class.
/// </summary>
protected IdentityDbContext()
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of Users.
/// </summary>
public DbSet<TUser> Users get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of User claims.
/// </summary>
public DbSet<TUserClaim> UserClaims get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of User logins.
/// </summary>
public DbSet<TUserLogin> UserLogins get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of User roles.
/// </summary>
public DbSet<TUserRole> UserRoles get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of User tokens.
/// </summary>
public DbSet<TUserToken> UserTokens get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of roles.
/// </summary>
public DbSet<TRole> Roles get; set;
/// <summary>
/// Gets or sets the <see cref="DbSetTEntity"/> of role claims.
/// </summary>
public DbSet<TRoleClaim> RoleClaims get; set;
/// <summary>
/// Configures the schema needed for the identity framework.
/// </summary>
/// <param name="builder">
/// The builder being used to construct the model for this context.
/// </param>
protected override void OnModelCreating(ModelBuilder builder)
builder.Entity<TUser>(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<TRole>(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<TUserClaim>(b =>
b.HasKey(uc => uc.Id);
b.ToTable("AspNetUserClaims");
);
builder.Entity<TRoleClaim>(b =>
b.HasKey(rc => rc.Id);
b.ToTable("AspNetRoleClaims");
);
builder.Entity<TUserRole>(b =>
b.HasKey(r => new r.UserId, r.RoleId );
b.ToTable("AspNetUserRoles");
);
builder.Entity<TUserLogin>(b =>
b.HasKey(l => new l.LoginProvider, l.ProviderKey );
b.ToTable("AspNetUserLogins");
);
builder.Entity<TUserToken>(b =>
b.HasKey(l => new l.UserId, l.LoginProvider, l.Name );
b.ToTable("AspNetUserTokens");
);
:
public class ApplicationDbContext
: IdentityDbContext
public ApplicationDbContext()
: base("DefaultConnection")
static ApplicationDbContext()
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
public static ApplicationDbContext Create()
return new ApplicationDbContext();
// Add additional items here as needed
基于源代码,如果我们想将IdentityDbContext与我们的DbContext合并,我们有两个选择: 第一选择: 创建一个DbContext,它继承自IdentityDbContext并可以访问这些类。
public class ApplicationDbContext : IdentityDbContext
public ApplicationDbContext(): base("DefaultConnection")
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().ToTable("user");
modelBuilder.Entity<ApplicationUser>().ToTable("user");
modelBuilder.Entity<IdentityRole>().ToTable("role");
以上是关于ASP.NET身份DbContext混淆的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET Core Authorize-Attribute 中使用带有 DbContext 的存储库:“无法访问已处置的对象”