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

Posted

技术标签:

【中文标题】实体类型“IdentityUserLogin<string>”需要定义一个主键[重复]【英文标题】:The entity type 'IdentityUserLogin<string>' requires a primary key to be defined [duplicate] 【发布时间】:2017-04-03 20:54:04 【问题描述】:

我在 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 一个主键是我的工作??它是一个 3rd 方类,我什至没有碰过它。我有以下简单的设置:

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

我的项目开源于:my github repo

如果有帮助的话。

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

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

如您所见,当我将 UserId 作为整数时,这又回来了,但我什至不确定 UserId 是否应该是它的 primaryKey。我可以得到其他错误而不是这个错误,也就是说

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

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

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

【问题讨论】:

【参考方案1】:

Identity 表的键映射在IdentityDbContextOnModelCreating 方法中,如果不调用此方法,您最终将得到您得到的错误。

你需要做的就是打电话。

protected override void OnModelCreating(ModelBuilder modelBuilder)

  base.OnModelCreating(modelBuilder);

原始答案(只是复制以供其他人参考以防万一)here

【讨论】:

我没有调用基础就覆盖了它,谢谢! 好的,所以我接受这个答案而不是我自己的答案,即使在我的情况下我已经有了那条线,但它没有解决它。考虑到我解释的错误,这显然是解决了很多人的问题。 为我节省了一天 我有一个类似的案例,问题是我错过了未添加到 OnModelCreating 的配置文件。一旦我添加了它们,一切都解决了。 – chdid 刚刚编辑 就我而言,当我添加 base.OnModelCreating(modelBuilder);它开始抛出 AspnetRoles 的 sql 异常不存在。所以我必须添加迁移和更新数据库才能使其工作。【参考方案2】:

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

实体类型“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);
 

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

难道不是因为您正在扩展一个 IdentityDbContext,它在层次结构中包含您现在忽略的 DbSet? 我现在不记得了,但我确实认为是这样的。上下文确实以某种方式引用了它们。 如果 IdentityDatabaseContext 中的某些实体存在于其他 DatabaseContext 中,EF 在主数据库上下文中从两个数据库上下文创建所有实体! .

以上是关于实体类型“IdentityUserLogin<string>”需要定义一个主键[重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥这违反了类型约束?

ASP.NET Identity 修改表名和主键类型

java怎么注解实体类,实现数据库类型与java类型对应映射?

symfony 5 表单实体类型过滤器选择基于选择的其他实体类型选择

实体框架 - 您能否将导入的存储过程的结果类型映射到自定义实体类型?

附加类型实体失败,因为相同类型的另一个实体已经具有相同的主键值。