ASP.NET Core Web API - 实体类型“IdentityUserRole<long>”需要定义主键

Posted

技术标签:

【中文标题】ASP.NET Core Web API - 实体类型“IdentityUserRole<long>”需要定义主键【英文标题】:ASP.NET Core Web API - The entity type 'IdentityUserRole<long>' requires a primary key to be defined 【发布时间】:2022-01-18 10:13:10 【问题描述】:

我正在 ASP.NET Core Web API 中实现 IdentityDbContext。

IdentityModel:

public class ApplicationUser : IdentityUser<long>

    public DateTime? LastLogin  get; set; 
    public ICollection<ApplicationUserRole> UserRoles  get; set; 


public class ApplicationRole : IdentityRole<long>

    public ICollection<ApplicationUserRole> UserRoles  get; set; 


public class ApplicationUserRole : IdentityUserRole<long>

    public virtual ApplicationUser User  get; set; 
    public virtual ApplicationRole Role  get; set; 

AppDbContext:

public class AppDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long, IdentityUserClaim<long>, ApplicationUserRole, IdentityUserLogin<long>, IdentityRoleClaim<long>, IdentityUserToken<long>>

    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    
    

    public DbSet<ApplicationRole> ApplicationRole  get; set; 
    public DbSet<ApplicationUserRole> ApplicationUserRole  get; set; 

    protected override void OnModelCreating(ModelBuilder builder)
    
        base.OnModelCreating(builder);
        this.SeedUsers(builder);
        this.SeedRoles(builder);
        this.SeedUserRoles(builder);

        builder.Entity<ApplicationUser>(entity =>
        
            entity.Property(u => u.Id).ValueGeneratedOnAdd();
            entity.HasIndex(u => u.Email).IsUnique();
        );
        builder.Entity<ApplicationRole>(entity =>
        
            entity.Property(r => r.Id).ValueGeneratedOnAdd();
            entity.HasIndex(r => r.Name).IsUnique();
        );
        builder.Entity<ApplicationUserRole>(userRole =>
        
            userRole.HasKey(ur => new  ur.UserId, ur.RoleId );

            userRole.HasOne(ur => ur.Role)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();

            userRole.HasOne(ur => ur.User)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();
        );
    
    private void SeedUsers(ModelBuilder builder)
    
        ApplicationUser user = new ApplicationUser()
        
            UserName = "Admin",
            NormalizedUserName = "ADMIN",
            Email = "admin@admin.com",
            SecurityStamp = Guid.NewGuid().ToString("D"),
            PhoneNumber = "+1234567890"
        ;

        PasswordHasher<ApplicationUser> passwordHasher = new PasswordHasher<ApplicationUser>();
        passwordHasher.HashPassword(user, "Admin*123");

        builder.Entity<ApplicationUser>().HasData(user);
    

    private void SeedRoles(ModelBuilder builder)
    
        builder.Entity<ApplicationRole>().HasData(
            new ApplicationRole()  Name = "Admin", ConcurrencyStamp = "1", NormalizedName = "ADMIN" ,
            new ApplicationRole()  Name = "User", ConcurrencyStamp = "2", NormalizedName = "USER" 
            );
    

    private void SeedUserRoles(ModelBuilder builder)
    
        builder.Entity<IdentityUserRole<long>>().HasData(
            new IdentityUserRole<long>()  RoleId = 1, UserId = 1 
            );
    

ID 是自动生成的。

当我执行 Add-Migration 时,我得到了这个错误:

实体类型“IdentityUserRole”需要定义一个主键。如果您打算使用无密钥实体类型,请在“OnModelCreating”中调用“HasNoKey”。有关无密钥实体类型的更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=2141943。

我该如何解决这个问题?

谢谢

【问题讨论】:

【参考方案1】:

你需要删除AppDbContext中的一些代码:

AppDbContext

public class AppDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long, IdentityUserClaim<long>, ApplicationUserRole, IdentityUserLogin<long>, IdentityRoleClaim<long>, IdentityUserToken<long>>
    
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        
        

        public DbSet<ApplicationRole> ApplicationRole  get; set; 
        public DbSet<ApplicationUserRole> ApplicationUserRole  get; set; 

        protected override void OnModelCreating(ModelBuilder builder)
        
            base.OnModelCreating(builder);
           

            builder.Entity<ApplicationUser>(entity =>
            
                entity.Property(u => u.Id).ValueGeneratedOnAdd();
                entity.HasIndex(u => u.Email).IsUnique();
            );
            builder.Entity<ApplicationRole>(entity =>
            
                entity.Property(r => r.Id).ValueGeneratedOnAdd();
                entity.HasIndex(r => r.Name).IsUnique();
            );
            
        
        private void SeedUsers(ModelBuilder builder)
        
            ApplicationUser user = new ApplicationUser()
            
                UserName = "Admin",
                NormalizedUserName = "ADMIN",
                Email = "admin@admin.com",
                SecurityStamp = Guid.NewGuid().ToString("D"),
                PhoneNumber = "+1234567890"
            ;

            PasswordHasher<ApplicationUser> passwordHasher = new PasswordHasher<ApplicationUser>();
            passwordHasher.HashPassword(user, "Admin*123");

            builder.Entity<ApplicationUser>().HasData(user);
        

        private void SeedRoles(ModelBuilder builder)
        
            builder.Entity<ApplicationRole>().HasData(
                new ApplicationRole()  Name = "Admin", ConcurrencyStamp = "1", NormalizedName = "ADMIN" ,
                new ApplicationRole()  Name = "User", ConcurrencyStamp = "2", NormalizedName = "USER" 
                );
        

        private void SeedUserRoles(ModelBuilder builder)
        
            builder.Entity<IdentityUserRole<long>>().HasData(
                new IdentityUserRole<long>()  RoleId = 1, UserId = 1 
                );
        
    

您可以阅读此文档以了解有关自定义身份的更多信息:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-3.1

【讨论】:

以上是关于ASP.NET Core Web API - 实体类型“IdentityUserRole<long>”需要定义主键的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

带有实体框架的 ASP.Net Core Web API 使用存储过程有啥好处吗? [关闭]

使用 OData 的 ASP.Net Core Web API 实现对于单个实体 URI 失败

ASP.NET Core Web API - 实体类型“IdentityUserRole<long>”需要定义主键

ASP.NET Core Web API - PUT 与 PATCH

Postman 收到简单的 ASP.NET Core Web API 的 404 错误