web-dev-qa-db-fra.com

InvalidOperationException: impossible de créer un DbSet pour 'Role' car ce type n'est pas inclus dans le modèle pour le contexte

La solution suivante fonctionne dans .net core 1.1, mais après la mise à niveau de 1.1 à 2.0, j'ai reçu l'erreur suivante:

InvalidOperationException: impossible de créer un DbSet pour 'Role' car ce type n'est pas inclus dans le modèle pour le contexte.

Lorsque l'utilisateur tente de se connecter et que l'instruction suivante est exécutée:

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

Qu'est-ce qui ne va pas?


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> 
17
001

Ajouté ceci et cela a fonctionné:

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

Les raisons les plus courantes pour 

Impossible de créer un DbSet pour 'THE-MODEL' car ce type n'est pas inclus dans le modèle pour le contexte

sont les suivants

  1. Le nom du modèle ne correspond pas au nom de la table dans la base de données 
  2. EntityFramework ne peut pas déterminer la méta requise par convention et vous ne l'utilisez pas.

dans votre cas, le rôle hérite d'IdentityRoleClaim et cela n'a pas été configuré et la convention par défaut a requis "Id" en tant que clé, mais je suppose qu'il ne possédait pas cette propriété, il a donc dû être configuré. Cela aurait également fonctionné si vous aviez créé une propriété dans Role telle que Id => new {UserId, RoleId}, ce qui, par convention, présenterait Id comme propriété de clé dans le cadre de l'entité.

6
Gurpreet

Vérifiez que votre AppDbContext n'est PAS hérité de DbContext mais qu'il devrait l'être à partir de IdentityDbContext<ApplicationUser>

6
MaylorTaylor

Si votre DbContext n'hérite pas d'IdentityUserContext, n'utilisez pas AddEntityFrameworkStores dans la méthode ConfigureServices. Remplacez-le par AddUserStore et AddRoleStore comme suit: 

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

Si vous vérifiez l'implémentation de la méthode AddEntityFrameworkStores, vous verrez qu'elle ajoute des magasins en recherchant des types génériques dans DbContext, en supposant qu'elle hérite d'IdentityUserContext. Quoi qu'il en soit, vous serez coincé avec les types de base Identity * pour les revendications ... qui généreront cette exception.

1
frontlinebg

Dans mon cas, cela se produisait parce que j'ajoutais manuellement des entités et que j'avais oublié d'ajouter la suivante sous DbContext. 

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

J'ai eu le même problème, c'était en raison de la mauvaise configuration d'IUserStore dans mon cas. J'utilise Autofac pour l'injection de dépendance et cette configuration a résolu mon problème:

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

Mes lecteurs de base de données IdentityDbContext

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

et tout ce que j'avais à faire était de créer un Userstore et de le donner à ma DI pour l'injecter dans la classe Signinmanager

0