InvalidOperationException:无法为' Role'创建DbSet。因为此类型未包含在上下文的模型中

时间:2017-10-16 00:27:22

标签: c# asp.net asp.net-mvc asp.net-identity .net-2.0

以下解决方案适用于.net核心1.1,但在从1.1升级到2.0后,我收到以下错误:

  

InvalidOperationException:无法为'角色'创建DbSet。因为此类型未包含在上下文的模型中。

当用户尝试登录并执行以下语句时:

var result = await _signInManager.PasswordSignInAsync(model.Email, 
                                model.Password, model.RememberMe, lockoutOnFailure: false);

有什么问题?

User.cs

public partial class User : IdentityUser<Guid>
{
    public string Name { get; set; }
}

IdentityEntities.cs

public partial class UserLogin : IdentityUserLogin<Guid>
{
}
public partial class UserRole : IdentityUserRole<Guid>
{
}
public partial class UserClaim : IdentityUserClaim<Guid>
{
}
public partial class Role : IdentityRole<Guid>
{
    public Role() : base()
    { 
    }

    public Role(string roleName)
    {
        Name = roleName;
    }
}
public partial class RoleClaim : IdentityRoleClaim<Guid>
{
}
public partial class UserToken : IdentityUserToken<Guid>
{
}

ConfigureServices

services.AddIdentity<User, Role> 

12 个答案:

答案 0 :(得分:11)

添加了这个并且有效:

builder.Entity<IdentityUserRole<Guid>>().HasKey(p => new { p.UserId, p.RoleId });

答案 1 :(得分:7)

的最常见原因
  

无法为&#39; THE-MODEL&#39;创建DbSet。因为这种类型不是   包含在上下文的模型中

如下

  1. 型号名称与数据库中的表名称
  2. 不匹配
  3. EntityFramework无法按惯例找出所需的元素 不要覆盖它。
  4. 在您的情况下,Role继承IdentityRoleClaim且未配置且需要默认约定&#34; Id&#34;作为关键,但我想它没有那个属性所以它必须配置。如果你在像Id =&gt;这样的角色中创建了属性,它也会有效。新的{UserId,RoleId},按惯例,它将Id作为实体框架的关键属性。

答案 2 :(得分:7)

您可以通过替换此问题来解决此问题

public class ApplicationDbContext : IdentityDbContext<AppUser>

与此

public class ApplicationDbContext : IdentityDbContext<AppUser, AppRole, string>

在最后一个参数中注意此字符串类型。

答案 3 :(得分:6)

检查您的AppDbContext是否不继承自DbContext,而应该继承自IdentityDbContext<ApplicationUser>

答案 4 :(得分:1)

如果您的DbContext不继承IdentityUserContext-请勿在ConfigureServices方法中使用AddEntityFrameworkStores。用AddUserStore和AddRoleStore替换它,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services
        .AddIdentity<MyUserType, MyRoleType>(...)
        .AddUserStore<UserStore<MyUserType, MyRoleType, MyDbContextType, MyKeyType, MyUserClaimType, MyUserRoleType, MyUserLoginType, MyUserTokenType, MyRoleClaimType>>()
        .AddRoleStore<RoleStore<MyRoleType, MyDbContextType, MyKeyType, MyUserRoleType, MyRoleClaimType>>();
    ...
}

如果检查AddEntityFrameworkStores方法的实现,您会发现它通过在DbContext中搜索通用类型来添加存储,并假设它继承了IdentityUserContext。无论如何,您将受困于声明的基本Identity *类型...会生成此异常。

答案 5 :(得分:0)

在我的情况下,这种情况正在发生,因为我手动添加实体,忘了在DbContext下添加下一个实体。

df=df.sort_values('int_column').assign(key=df.groupby('my_column').cumcount())
df['Value']=list(zip(df['some_id'],df['int_column']))
s=df.pivot(index='key',columns='my_column',values='Value')
s
Out[397]: 
my_column      id_1      id_2      id_3
key                                    
0          (xx4, 1)  (xx2, 1)  (xx2, 3)
1          (xx1, 3)  (xx1, 4)  (xx1, 5)
2          (xx3, 4)  (xx3, 8)  (xx3, 9)
3          (xx2, 6)      None      None

答案 6 :(得分:0)

我遇到了类似的问题,这是由于我的情况下IUserStore的配置错误。我正在使用Autofac进行依赖项注入,此配置解决了我的问题:

var dbContextParameter = new ResolvedParameter((pi, ctx) => pi.ParameterType == typeof(IdentityDbContext),
                                                    (pi, ctx) => ctx.Resolve<DatabaseContext>());

  builder.RegisterType<UserStore<User, Role, DatabaseContext, Guid,UserClaim,UsersInRole,UserLogin,UserToken,RoleClaim>>()
            .As<IUserStore<User>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();
        builder.RegisterType<CustomRoleStore>()
            //RegisterType<UserStore<User, Role, DatabaseContext, Guid,UserClaim,UsersInRole,UserLogin,UserToken,RoleClaim>>()
            .As<IRoleStore<Role>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();

我的databaseContext从IdentityDbContext驱动

 public class DatabaseContext : IdentityDbContext<User, Role, Guid, UserClaim
    , UsersInRole, UserLogin, RoleClaim, UserToken
    >, IDatabaseContext

我要做的就是创建一个Userstore并将其提供给我的DI以注入到signinmanager类中

答案 7 :(得分:0)

我通过添加以下内容解决了此问题:

public DbSet<ApplicationRole> ApplicationRoles { get; set; }

到我的DbContext

答案 8 :(得分:0)

使用模型构建器在DBContext中添加模型。 如下编写数据库上下文类。

 public partial class CDBContext : DbContext
   {

    public CDBContext (string ConnectionString) : base(new DbContextOptionsBuilder().UseSqlServer(ConnectionString).Options)
    {

    }  
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Query<MediaData>();            
    }

答案 9 :(得分:0)

就我而言,我将错误的类传递给EF DbContext 。我有2个班级,第一个班级"Accounting"和第二个班级"Account"。我发送了“ Accounting”,其中EF-Dbcontext没有该实体并返回了

Cannot create a DbSet for 'Accounting' because this type is not included in the model for the context.

请检查您要发送到 DbContext 的班级。

答案 10 :(得分:0)

  1. 您需要检查您的 AppDbContext 是否继承自 IdentityDbContext。您的 AppDbContext 必须从 IdentityDbContext 继承。

  2. 然后 OnModelCreating 你需要像下面这样映射关系 -

    builder.Entity<ApplicationUserRole>(userRole =>
         {
             userRole.HasKey(ur => new { ur.UserId, ur.RoleId });
    
             userRole.HasOne(ur => ur.Role)
                 .WithMany(r => r.UserRoles)
                 .HasForeignKey(ur => ur.RoleId)
                 .IsRequired();
    
             userRole.HasOne(ur => ur.User)
                 .WithMany(r => r.UserRoles)
                 .HasForeignKey(ur => ur.UserId)
                 .IsRequired();
         });
    
  3. 整个应用程序数据库上下文看起来像 -

           using Core.Entities.Identity;
           using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
           using Microsoft.EntityFrameworkCore;
    
           namespace Infrastructure.Identity
           {
               public class AppIdentityDbContext : IdentityDbContext<AppUser, ApplicationRole, 
               string, IdentityUserClaim<string>,
               ApplicationUserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>, 
               IdentityUserToken<string>>
               {
                  public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options) : 
                  base(options)
             {
             }
    
             protected override void OnModelCreating(ModelBuilder builder) 
             {
                base.OnModelCreating(builder);
    
                 builder.Entity<ApplicationUserRole>(userRole =>
                 {
                     userRole.HasKey(ur => new { ur.UserId, ur.RoleId });
    
                     userRole.HasOne(ur => ur.Role)
                         .WithMany(r => r.UserRoles)
                         .HasForeignKey(ur => ur.RoleId)
                         .IsRequired();
    
                     userRole.HasOne(ur => ur.User)
                         .WithMany(r => r.UserRoles)
                         .HasForeignKey(ur => ur.UserId)
                         .IsRequired();
                 });
    
              }
           }
        }
    

    希望您的问题得到解决。

答案 11 :(得分:-1)

我遇到了这个问题。为了解决这个问题,我在Entity Config类中做了一些更改。

public class AspNetUserClaimsConfig : IEntityTypeConfiguration<IdentityUserClaim<string>>
{
    public void Configure(EntityTypeBuilder<IdentityUserClaim<string>> builder)
    {
        builder.ToTable("AspNetUserClaims", "Identity");

        // Primary key
         builder.HasKey(uc => uc.Id);
    }
}

我是这样做的:

public class IdentityContext : DbContext
{
    public IdentityContext(DbContextOptions<IdentityContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new ApplicationUsersConfig());

        base.OnModelCreating(modelBuilder);
    }
}