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>”需要定义主键