实体类型'IdentityUserLogin <string>'需要定义主键

Den*_*and 19 c# entity-framework asp.net-identity asp.net-core

我在linux上使用dotnet core 1.1,当我想从我的常规dbContext中分离identityContext时,我遇到问题,每当我在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
Run Code Online (Sandbox Code Playgroud)

因此,该行抛出异常:实体类型'IdentityUserLogin'需要定义主键

我根本不明白这一点,为什么我的工作是给IdentityUserLogin一个主键?它是一个第三方类,我甚至没有触及它.我有以下简单的设置:

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


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

在我的启动中,我按以下方式配置身份框架:

configureServices:

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

配置:

 app.UseIdentity();
Run Code Online (Sandbox Code Playgroud)

我的项目是开源的:我的github repo

如果这有帮助.

我尝试过很多东西.最有希望的两个是派生出这个通用节目中使用的所有类,并明确地传递它们,试图将它们的所有键更改为整数等.而这只是用int而不是字符串给出完全相同的错误.我尝试的另一种方式是在内部执行以下操作,OnModelCreating以通过例如:IdentityUserLogin为主键提供:

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

正如你所看到的,当我将UserId作为整数时,这又回来了,但我甚至不确定UserId是否应该是它的primaryKey.我说可以得到其他错误,而不是这个错误

IdentityUserLogin是层次结构的一部分,它没有鉴别器值

但如果我有鉴别器值,它最终会回到这个错误.我认为最奇怪的部分是我有与UnicornStore github示例完全相同的实现,它也使用了一些身份框架....所以我真的需要你的帮助.可以通过下载项目,复制default.appsettings.jsonappsettings.json,放入有效的连接字符串dotnet restore,运行来重现此错误dotnet run --environment Development.

我甚至试图改变实现以使用MSSQL数据库而不是MySQL,但这给出了完全相同的错误.

imm*_*rza 71

身份表的键在OnModelCreating方法中映射,IdentityDbContext如果没有调用此方法,您将最终得到您所获得的错误.

你需要做的就是打电话.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);
}
Run Code Online (Sandbox Code Playgroud)

原来答案(刚才复制为以防万一对方的引用)在这里

  • 我是在不通知基地的情况下将其覆盖,谢谢! (2认同)
  • 这!我找到了 400 行的答案,而我只需要这个 (2认同)

Den*_*and 14

好的。所以我会尝试回答我自己的问题,因为我确实克服了它。仍然可以按照 OP 中的 github 链接,查看我遇到错误的项目。

主要是出了什么问题,是我在尝试迁移时遇到了这个错误,ApplicationDbContext : IDentityContext 但实际上该错误是基于应用程序中的其他 dbContext 引发的,当我尝试在该应用程序上运行迁移时。我仍然有点不知道为什么其他 DbContext 会在我没有在任何地方提到的这些 Identity 实体上进行选择,我认为 dbcontext 似乎对 OnModelCreating 方法中未提及的实体有所了解,这很奇怪。无论如何 - 当我发现问题不是 IdentityDbContext 时,我只是在引发错误的上下文的 OnModelCreating 中添加了以下内容:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Ignore <IdentityUserLogin<string>>();
            modelBuilder.Ignore <IdentityUserRole<string>>();
            modelBuilder.Ignore<IdentityUserClaim<string>>();
            modelBuilder.Ignore<IdentityUserToken<string>>();
            modelBuilder.Ignore<IdentityUser<string>>();
            modelBuilder.Ignore<ApplicationUser>();
Run Code Online (Sandbox Code Playgroud)

所以......我仍然想知道为什么我的上下文会在与这些实体无关的情况下接收它们,而且我非常担心每次添加上下文时我都必须排除模型而不是包含它们。

  • 是不是因为您正在扩展一个 IdentityDbContext,它在层次结构中包含您现在忽略的 DbSet? (2认同)

sus*_*oo_ 6

我有一个与您最初的问题有关的类似问题,其中

实体类型“IdentityUserLogin”需要定义一个主键。

虽然我认为您忽略实体的解决方案似乎有效,但我只是想为那些确实想要为每个实体分配主键的人提供另一种解决方案。问题是,无论何时创建实体,DbContext都需要跟踪每个实体的主键 - 因此,您必须分配它。

请参阅下面的示例,其中ProjectTarget是我的实体,并且我为每个实体分配了一个我想用作每个实体的主键的属性。

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<Project>().HasKey(m => m.ProjectPath);
    builder.Entity<Target>().HasKey(m => m.Guid);
    base.OnModelCreating(builder);
} 
Run Code Online (Sandbox Code Playgroud)

在您确定并分配应将哪个属性指定为该实体的主键后,错误将消失。