The entity type 'IdentityUserLogin<string>' requires a primary key to be defined

DenLilleMand picture DenLilleMand · Nov 20, 2016 · Viewed 39.2k times · Source

i am using dotnet core 1.1 on linux, and i am having issues when i want to split up the identityContext from my regular dbContext, whenever i run the following line in my startup.cs --> configure:

//... some other services
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
    serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate();
    //running other database.migrations here + seeding data. But it is the line above that causes problems

So this line throws the exception: The entity type 'IdentityUserLogin' requires a primary key to be defined

I simply don't understand this, why is it my job to give the IdentityUserLogin a primary key??, it is a 3rd party class and i haven't even touched it. I have the following simple setup:

namespace EsportshubApi.Models
{
    public class ApplicationDbContext :  IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        {
        }

        public ApplicationDbContext()
        {

        }

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


        }
    }
}

And the applicationUser:

namespace EsportshubApi.Models.Entities
{

    public class ApplicationUser : IdentityUser
    {
        public ApplicationUser() { }

        public static ApplicationUserBuilder Builder()
        {
            return new ApplicationUserBuilder(new ApplicationUser());
        }

        public int AccountId { get; set; }
        public Guid AccountGuid { get; set; }
        public string Salt { get; set; }
        public bool Verified { get; set; }
        public string Checksum { get; set; }
        public string Password { get; set; }
        public DateTime Created { get; set; }
        public DateTime Updated { get; set; }
    }

}

In my startup i am configuring the identity framework the following way:

configureServices:

services.AddEntityFrameworkSqlServer().AddMySQL().AddDbContext<ApplicationDbContext>(options =>
                    options.UseMySQL(config["ConnectionStrings:DefaultConnection"]));

And

Configure:

 app.UseIdentity();

My project is opensourced at : my github repo

if that helps.

I have tried a lot of things. The two most promising was deriving all of the classes used in this generic show, and passing them in explicitly, tried to change all of their keys to ints etc. And that gave the exact same error just with int instead of string. The other way i tried was to do the following inside of OnModelCreating to give IdentityUserLogin a primary key by e.g :

 modelBuilder.Entity<IdentityUserLogin<int>>()
            .Property(login => login.UserId)
            .ForMySQLHasColumnType("PK")
            .UseSqlServerIdentityColumn()
            .UseMySQLAutoIncrementColumn("AI");

As you can see, this was back when i had UserId as a integer, but i am not even sure if the UserId should be its primaryKey. I can get other errors instead of this one, that says

IdentityUserLogin is part of a hierarchy, and it has no discriminator values

But if I had discriminator values it eventually just goes back to this error. The weirdest part i think is that i have the EXACT same implementation as the UnicornStore github example, that uses a bit of the identity framework as well .... So i really need your help guys. Can reproduce this error by downloading the project, copying the default.appsettings.json into appsettings.json, put in a valid connectionstring, dotnet restore, run with dotnet run --environment Development.

I even tried to change out the implementation to use a MSSQL database instead of MySQL, but that gave the exact same error.

Answer

immirza picture immirza · Aug 20, 2017

keys of Identity tables are mapped in OnModelCreating method of IdentityDbContext and if this method is not called, you will end up getting the error that you got.

All you need to do is call.

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

The original answer (just copied for other's reference just in case) here