InvalidOperationException: невозможно создать DbSet для "роли", потому что этот тип не включен в модель для контекста

Следующее решение работает в .net core 1.1, но после обновления с 1.1 до 2.0 я получил следующую ошибку:

InvalidOperationException: невозможно создать DbSet для 'Role', потому что этот тип не включен в модель для контекста.

Когда пользователь пытается войти в систему и выполняется следующий оператор:

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> 

Ответы

Ответ 1

Добавлено это, и он работал:

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

Ответ 2

Наиболее распространенные причины

Невозможно создать DbSet для 'THE-MODEL', потому что этот тип не является включен в модель для контекста

имеют вид

  • Имя модели не совпадает с именем таблицы в базе данных
  • EntityFramework не может определить требуемую метаконференцию, и вы имеете не переусердствуйте.

в вашем случае Роль наследует IdentityRoleClaim, и это не было настроено, и для соглашения по умолчанию требовалось "Id" в качестве ключа, но я полагаю, что у него не было этого свойства, поэтому его нужно было настроить. Это также сработало бы, если вы создали свойство в роли, такое как Id = > new {UserId, RoleId}, которое по условному объявлению представляет Id как свойство ключа для структуры сущности.

Ответ 3

Убедитесь, что ваш AppDbContext НЕ унаследован от DbContext но вместо этого он должен быть унаследован от IdentityDbContext<ApplicationUser>

Ответ 4

Если ваш DbContext не наследует IdentityUserContext - не используйте AddEntityFrameworkStores в методе ConfigureServices. Замените его на 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

Я исправил это, добавив:

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

на мой DbContext.

Ответ 6

В моем случае это происходило потому, что я вручную добавлял сущности и забыл добавить следующую под DbContext.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    new CryptoCoinsMap(modelBuilder.Entity<CoinMaster>());
    new CoinQuotesDailyMap(modelBuilder.Entity<CoinQuotesDaily>());
}

Ответ 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();

Моя база данныхContext дисков от IdentityDbContext

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

и все, что мне нужно было сделать, это создать хранилище пользователей и передать его моему DI для добавления в класс signinmanager

Ответ 8

Добавьте ваши модели в 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

У меня была эта проблема. Чтобы исправить это, я сделал некоторые изменения в классе 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);
    }
}