实体类型“IdentityUserLogin<string>”需要定义主键[重复]

问题描述 投票:0回答:3

我在Linux上使用dotnet core 1.1,当我想从常规dbContext中分离identityContext时,每当我在startup.cs中运行以下行时就会遇到问题 --> 配置:

//... 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

因此这一行抛出异常:实体类型“IdentityUserLogin”需要定义主键

我根本不明白这一点,为什么我的工作是给 IdentityUserLogin 主键??,它是第 3 方类,我什至没有碰过它。我有以下简单的设置:

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


        }
    }
}

应用程序用户:

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

}

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

配置服务:

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

还有

配置:

 app.UseIdentity();

我的项目开源于:我的 github 存储库

如果有帮助的话。

我尝试了很多事情。最有希望的两个是派生此通用显示中使用的所有类,并显式传递它们,尝试将它们的所有键更改为整数等。这仅使用

int
而不是字符串给出了完全相同的错误。 我尝试的另一种方法是在
OnModelCreating
内部执行以下操作,为 IdentityUserLogin 提供主键,例如:

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

正如您所看到的,当我将 UserId 作为整数时,我什至不确定 UserId 是否应该是其主键。我可以得到其他错误而不是这个错误,也就是说

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

但是如果我有鉴别器值,它最终只会回到这个错误。我认为最奇怪的部分是我有与 UnicornStore github 示例完全相同的实现,它也使用了一些身份框架......所以我真的需要你们的帮助。可以通过下载项目、将

default.appsettings.json
复制到
appsettings.json
、放入有效的连接字符串
dotnet restore
、使用
dotnet run --environment Development
运行来重现此错误。

我什至尝试更改实现以使用 MSSQL 数据库而不是 MySQL,但这给出了完全相同的错误。

c# entity-framework asp.net-core asp.net-identity
3个回答
430
投票

Identity 表的键在

OnModelCreating
IdentityDbContext
方法中映射,如果不调用此方法,您最终将得到您得到的错误。

您所需要做的就是打电话。

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

原答案(只是复制给其他人参考以防万一)这里


20
投票

好的。所以我会尝试回答我自己的问题,因为我确实克服了它。仍然可以按照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>();

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


6
投票

我遇到了与您最初的问题相关的类似问题

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

虽然我认为您忽略实体的解决方案似乎有效,但我只是想为那些真正想要为每个实体分配主键的人提供另一个解决方案。问题是,每当您创建一个实体时,

DbContext
都会想要跟踪每个实体的主键 - 因此,您必须分配它。

请参阅下面的示例,其中

Project
Target
是我的实体,我已为每个实体分配了一个我想用作每个实体的主键的属性。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.