Asp.net Core 6.0 InvalidOperationException:无法为“IdentityUser”创建 DbSet,因为此类型未包含在上下文的模型中

问题描述 投票:0回答:1

我开发了一个网络应用程序,我想在其中使用 Microsoft Identity(与个人用户)和 Postgresql 作为数据库。 在此 Web 应用程序中,我将 ef core dbcontext 存储在单独的项目/层中,并以这种方式设置 Program.cs 启动(我省略了其他行):

var builder = WebApplication.CreateBuilder(args);
    
// getting connection string from Postgresql db
var connectionString = builder.Configuration.GetConnectionString("NINIVE_DB");

//add dbcontext of the referenced project        
builder.Services.AddDbContext<NiniveContext>(options =>
        options.UseNpgsql(connectionString));
        
//set the Postgresql db as a source of the identity users   
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<NiniveContext>();

但是当我尝试使用登录页面时,我收到了我在这篇文章的对象中指定的错误。 我检查 DbContext 类,找到了身份请求的所有表。 这是 DbContext 类的第一部分:

public partial class NiniveContext : DbContext
{
    public NiniveContext()
    {
    }

    public NiniveContext(DbContextOptions<NiniveContext> options)
        : base(options)
    {
    }

    public virtual DbSet<AspNetRole> AspNetRoles { get; set; }

    public virtual DbSet<AspNetRoleClaim> AspNetRoleClaims { get; set; }

    public virtual DbSet<AspNetUser> AspNetUsers { get; set; }

    public virtual DbSet<AspNetUserClaim> AspNetUserClaims { get; set; }

    public virtual DbSet<AspNetUserLogin> AspNetUserLogins { get; set; }

    public virtual DbSet<AspNetUserToken> AspNetUserTokens { get; set; }

我看过很多文章,但从来没有对我有用! 对此有什么想法吗? 非常感谢!

asp.net-mvc asp.net-core entity-framework-core asp.net-identity
1个回答
0
投票

您可以覆盖身份框架类或按原样使用它们。您的示例中的

AspNetUser
将是 Identity Framework 中包含的
IdentityUser
类的重写类之一。请注意,您不需要覆盖所有这些。根据您的授权设置,您可以选择仅基于角色声明(权限)授权、仅基于用户声明(权限)授权或两者的组合

如果您计划对它们使用任何类型的注释,无论是用于数据库建模、模型验证还是任何其他类型,您可能需要覆盖包含的类,如下所示:

public class AspNetRole :      IdentityRole<(primary key type)> { }
public class AspNetRoleClaim : IdentityRoleClaim<(primary key type)> { }
public class AspNetUser :      IdentityUser<(primary key type)> { }
public class AspNetUserClaim : IdentityUserClaim<(primary key type)> { }
public class AspNetUserLogin:  IdentityUserLogin<(primary key type)> { }
public class AspNetUserToken : IdentityUserToken<(primary key type)> { }
public class AspNetUserRole :  IdentityUserRole<(primary key type)> { }

您还应该为身份配置创建一个不同的上下文类,因为它实现

IdentityDbContext
而不是实体框架中的
DbContext
。这个类可以采用几个不同的方法签名,具体取决于您实现或未实现的包含类,根据您的授权设置

这并不一定意味着数据需要位于单独的数据库中,但是,它们只是需要不同的 Context 类。例如,它们可以放置在同一数据库中但处于不同的模式下。这是一个示例,上面的所有派生类都实现了角色和用户声明:

public class NiniveIdentityContext :
    IdentityDbContext<AspNetUser, AspNetRole, Guid,
    AspNetUserClaim, AspNetUserRole, AspNetUserLogin,
    AspNetRoleClaim, AspNetUserToken> { }

然后您的应用程序上下文类将为您的应用程序数据实现

DbContext

public class NiniveContext : DbContext { }

然后在设置应用程序时,您可以像这样使用它们:

var builder = WebApplication.CreateBuilder(args);

// getting connection string from PostgreSQL DB
var connectionString = builder.Configuration
    .GetConnectionString("NINIVE_DB");

// getting connection string from PostgreSQL DB for Identity connection
var connectionIdentityString = builder.Configuration
    .GetConnectionString("NINIVE_IDENTITY_DB");

// add DbContext of the referenced project
builder.Services
    .AddDbContext<NiniveContext>(options => options.UseNpgSql(connectionString));

// add IdentityDbContext of the current project
builder.Services
    .AddDbContext<NiniveIdentityContext>(options => options.UseNpgSql(connectionIdentityString));

// set the PostgreSQL DB as a source of the Identity users   
builder.Services
    .AddDefaultIdentity<AspNetUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<NiniveIdentityContext>();
© www.soinside.com 2019 - 2024. All rights reserved.