53

The following solution works in .net core 1.1, but after upgrading from 1.1 to 2.0, I received the following error:

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

When the user attempts to log in and the following statement is executed:

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

What is wrong?


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> 
001
  • 62,807
  • 94
  • 230
  • 350

14 Answers14

31

Check that your AppDbContext is NOT inherited from DbContext but instead it should be inherited from IdentityDbContext<ApplicationUser>

MaylorTaylor
  • 4,671
  • 16
  • 47
  • 76
  • 1
    Unfortunately, this is no option if your `ApplicationUser` inherits `IdentityUser` for a different key type, as IdentityDbContext has the generic restriction `where T : IdentityUser`. – Martin Braun Feb 11 '19 at 00:49
  • 1
    This actually sorted my issue. Originally, the ApplicationDbContext was inheriting from IdentityDbContext (without specifying the custom user class). Once specified, the migration recognised and added the changes. Thanks, @MaylorTaylor! – army Feb 23 '19 at 23:51
21

Added this and it worked:

builder.Entity<IdentityUserRole<Guid>>().HasKey(p => new { p.UserId, p.RoleId });
001
  • 62,807
  • 94
  • 230
  • 350
16

The most common reasons for

Cannot create a DbSet for 'THE-MODEL' because this type is not included in the model for the context

are as follows

  1. The model name does not match with the table name in database
  2. EntityFramework cannot figure out required meta by convention and you have not overriden it.

in your case Role inherits IdentityRoleClaim and that was not configured and default convention required "Id" as key but i suppose it did not have that property so it had to be configured. It would also have worked if you created property in Role like Id => new{UserId,RoleId} which would by convention present Id as the key property to entity framework.

Gurpreet
  • 1,382
  • 11
  • 24
10

You can fix the issue by replacing this

public class ApplicationDbContext : IdentityDbContext<AppUser>

with this

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

notice this string type in the last argument.

Munam Yousuf
  • 431
  • 1
  • 6
  • 17
9

If your DbContext doesn't inherit IdentityUserContext - don't use AddEntityFrameworkStores in the ConfigureServices method. Substitute it with AddUserStore and AddRoleStore as follows:

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

If you check the implementation of the AddEntityFrameworkStores method you'll see that it adds stores via searching for generic types in the DbContext, assuming that it inherits IdentityUserContext. Regardless, you'll be stuck with the base Identity* types for claims ... which will generate this exception.

frontlinebg
  • 423
  • 5
  • 5
  • This is the right thing to do, thank you so much. Further notice: `UserStore` and `RoleStore` are in the `Microsoft.AspNetCore.Identity.EntityFrameworkCore` namespace. – Martin Braun Feb 11 '19 at 01:00
4

I fixed this by adding:

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

to my DbContext.

Simon Morgan
  • 2,018
  • 5
  • 23
  • 36
1

I had the same issue and I found that I didn't include it in the RoleStore and in the UserStore so, You need to do the following In the ApplicationDbContext

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

You need to add Role, UserRole in the stores as follows:

  1. create a class that inherits from RoleStore as follows

    public class AppRoleStore : RoleStore<Role, ApplicaitonDbContext, GUID, UserRole, RoleClaim>{}

2)Create class for the UserStore as follow

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

I had the similar problem, this was from the bad configuration for IUserStore in my case. I'm using Autofac for dependency injection and this configuration solved my problem:

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

My databaseContext drives from IdentityDbContext

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

and all I had to do was to Create a Userstore and give it to my DI to inject into signinmanager class

0

Add your models in the DBContext using model builder. Write your DB Context class as below.

 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>();            
    }
Saurabh Raoot
  • 1,303
  • 3
  • 26
  • 31
0

In my case I passed wrong class to EF DbContext. I had 2 classes, first one "Accounting" and the second one "Account". I sent "Accounting" , which EF-Dbcontext didn't have the entity and returned

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

Please check your class, which you want to send to your DbContext.

Saeed
  • 3,415
  • 3
  • 24
  • 41
0
  1. You need to check that your AppDbContext is inherited from IdentityDbContext or not. Your AppDbContext must inherit from IdentityDbContext.

  2. Then OnModelCreating you need to map relations like in below -

    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. Overall Application Db Context will looks like -

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

    Hope your problem will resolve.

June7
  • 19,874
  • 8
  • 24
  • 34
Shalim Ahmed
  • 259
  • 3
  • 6
0

I had this error as well, guide to get it working using EF Core 5.0 and EF Core 6.0 here:

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

Ogglas
  • 62,132
  • 37
  • 328
  • 418
0

Also had this problem. I was calling a stored procedure and passing back a scalar value by name that did not correspond to table structure at all:

result = db.Set<*Object*>()
    .FromSqlRaw($"EXECUTE [dbo].[*StoredProcedure*] {*var*}")
    .AsEnumerable()
    .First().*ScalarValueFromProcedure*;

Object name differed from the table DbSet name. It worked initially, but somehow broke along the way. Creating a DbSet<Object> fixed it.

-1

I had this problem. To fixed it, I did some changes in my Entity Config Class.

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

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

In my context I did this:

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

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

        base.OnModelCreating(modelBuilder);
    }
}