【问题标题】:InvalidOperationException: Cannot create a DbSet for 'Role' because this type is not included in the model for the contextInvalidOperationException:无法为“角色”创建 DbSet,因为此类型未包含在上下文模型中
【发布时间】:2017-10-16 00:27:21
【问题描述】:

以下解决方案适用于 .net core 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>
{
}

配置服务

services.AddIdentity<User, Role> 

【问题讨论】:

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


    【解决方案1】:

    检查您的AppDbContext 不是继承自DbContext,而是应该继承自IdentityDbContext&lt;ApplicationUser&gt;

    【讨论】:

    • 不幸的是,如果您的 ApplicationUser 为不同的键类型继承 IdentityUser&lt;T&gt;,则这是没有选择的,因为 IdentityDbContext 具有通用限制 where T : IdentityUser
    • 这实际上解决了我的问题。最初,ApplicationDbContext 是从 IdentityDbContext 继承的(没有指定自定义用户类)。指定后,迁移会识别并添加更改。谢谢,@MaylorTaylor!
    【解决方案2】:

    添加了这个并且它起作用了:

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

    【讨论】:

    • 当我这样做时,会在 SQL Server 数据库中创建一个新表“IdentityUserRole”。我已经添加了builder.Entity().HasKey(ur => new { ur.UserId, ur.RoleId }),为什么还不够呢?
    • 在哪里添加的?
    • @niico 放入OnModelCreating
    【解决方案3】:

    最常见的原因

    无法为“THE-MODEL”创建 DbSet,因为该类型不是 包含在上下文模型中

    如下

    1. 模型名与数据库中的表名不匹配
    2. EntityFramework 无法按照惯例找出所需的元数据,而您有 不要覆盖它。

    在您的情况下,角色继承了 IdentityRoleClaim 并且未配置,默认约定需要“Id”作为键,但我想它没有该属性,因此必须对其进行配置。如果您在角色中创建像 Id => new{UserId,RoleId} 这样的属性,它也会起作用,按照惯例,它将 Id 作为实体框架的关键属性。

    【讨论】:

      【解决方案4】:

      你可以通过替换来解决这个问题

      public class ApplicationDbContext : IdentityDbContext&lt;AppUser&gt;

      有了这个

      public class ApplicationDbContext : IdentityDbContext&lt;AppUser, AppRole, string&gt;

      注意最后一个参数中的这个字符串类型。

      【讨论】:

        【解决方案5】:

        如果您的 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* 类型卡住......这将产生此异常。

        【讨论】:

        • 这是正确的做法,非常感谢。进一步通知:UserStoreRoleStoreMicrosoft.AspNetCore.Identity.EntityFrameworkCore 命名空间中。
        【解决方案6】:

        我通过添加解决了这个问题:

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

        致我的DbContext

        【讨论】:

          【解决方案7】:

          我遇到了类似的问题,在我的情况下,这是由于 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
          

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

          【讨论】:

            【解决方案8】:

            使用模型构建器在 DBContext 中添加您的模型。 如下编写您的 DB Context 类。

             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】:

              在我的例子中,我将错误的类传递给了 EF DbContext。我有两节课,第一节 "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】:
                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. 整个应用程序 Db 上下文看起来像 -

                         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】:

                  我遇到了同样的问题,但我发现我没有将它包含在 RoleStoreUserStore 中 因此,您需要执行以下操作 在 ApplicationDbContext 中

                  public class ApplicationDbContext: IdentityDbContext<User, Role, GUID, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
                  {}
                  

                  您需要在stores中添加Role、UserRole,如下:

                  1. 创建一个继承自 RoleStore 的类,如下所示

                    public class AppRoleStore : RoleStore&lt;Role, ApplicaitonDbContext, GUID, UserRole, RoleClaim&gt;{}

                  2)如下为 UserStore 创建类

                  public class AppUserStore : UserStore<User, Role, ApplicationDbContext, GUID, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>
                      {}
                  

                  【讨论】:

                    【解决方案12】:

                    我也遇到了这个错误,请在此处使用 EF Core 5.0 和 EF Core 6.0 进行指导:

                    https://stackoverflow.com/a/71321924/3850405

                    【讨论】:

                      【解决方案13】:

                      我遇到了这个问题。为了修复它,我在我的实体配置类中做了一些更改。

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

                      【讨论】:

                        猜你喜欢
                        • 2019-08-16
                        • 2019-07-13
                        • 2019-07-10
                        • 1970-01-01
                        • 2018-10-20
                        • 1970-01-01
                        • 2022-01-08
                        • 2020-03-09
                        • 2019-01-04
                        相关资源
                        最近更新 更多