我已经有一个包含身份用户表的数据库(AspNetUser,AspRole,...)。我首先使用数据库来生成模型,我已经在
program.cs
中配置了所有必要的服务。该项目运行良好,直到我开始使用与身份相关的服务(例如:UserManager<AppUser>
)。它导致了很多异常(不可数)。我问了人工智能并用谷歌搜索了很多,但似乎希望已经破灭了。
这是生成的所有模型: 实体模型
Program.cs
配置:
配置
以下是一些例外情况,我发现了一篇具有相同问题但对我不起作用的帖子:在此处查看详细信息
不能将表“appuserroles”用于实体类型“appuserrole”,因为它用于实体类型“appuserrole(字典
Npgsql.PostgresException(0x80004005):42P01:关系“AppUser”不存在。
System.InvalidOperationException:无法将表“AppRoleClaims”用于实体类型“IdentityRoleClaim
这是我的数据库上下文:
public partial class MyUserContext : IdentityDbContext<AspNetUser, IdentityRole<Guid>, Guid>
{
public MyUserContext()
{
}
public MyUserContext(DbContextOptions<MyUserContext> options)
: base(options)
{
}
public virtual DbSet<AspNetRole> AspNetRoles { get; set; }
public virtual DbSet<AspNetRoleClaim> AspNetRoleClaims { get; set; }
public virtual DbSet<AspNetUser> AspNetUsers { get; set; }
public virtual DbSet<AspNetUserClaim> AspNetUserClaims { get; set; }
public virtual DbSet<AspNetUserLogin> AspNetUserLogins { get; set; }
public virtual DbSet<AspNetUserToken> AspNetUserTokens { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer("server=(local);database=MyUser;Trusted_Connection=True;TrustServerCertificate=True;uid=sa;pwd=T@n12345678901;");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AspNetRole>(entity =>
{
entity.HasIndex(e => e.NormalizedName, "RoleNameIndex")
.IsUnique()
.HasFilter("([NormalizedName] IS NOT NULL)");
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Name).HasMaxLength(256);
entity.Property(e => e.NormalizedName).HasMaxLength(256);
});
modelBuilder.Entity<AspNetRoleClaim>(entity =>
{
entity.HasIndex(e => e.RoleId, "IX_AspNetRoleClaims_RoleId");
entity.HasOne(d => d.Role).WithMany(p => p.AspNetRoleClaims).HasForeignKey(d => d.RoleId);
});
modelBuilder.Entity<AspNetUser>(entity =>
{
entity.HasIndex(e => e.NormalizedEmail, "EmailIndex");
entity.HasIndex(e => e.NormalizedUserName, "UserNameIndex")
.IsUnique()
.HasFilter("([NormalizedUserName] IS NOT NULL)");
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Email).HasMaxLength(256);
entity.Property(e => e.NormalizedEmail).HasMaxLength(256);
entity.Property(e => e.NormalizedUserName).HasMaxLength(256);
entity.Property(e => e.UserName).HasMaxLength(256);
entity.HasMany(d => d.Roles).WithMany(p => p.Users)
.UsingEntity<Dictionary<string, object>>(
"AspNetUserRole",
r => r.HasOne<AspNetRole>().WithMany().HasForeignKey("RoleId"),
l => l.HasOne<AspNetUser>().WithMany().HasForeignKey("UserId"),
j =>
{
j.HasKey("UserId", "RoleId");
j.ToTable("AspNetUserRoles");
j.HasIndex(new[] { "RoleId" }, "IX_AspNetUserRoles_RoleId");
});
});
modelBuilder.Entity<AspNetUserClaim>(entity =>
{
entity.HasIndex(e => e.UserId, "IX_AspNetUserClaims_UserId");
entity.HasOne(d => d.User).WithMany(p => p.AspNetUserClaims).HasForeignKey(d => d.UserId);
});
modelBuilder.Entity<AspNetUserLogin>(entity =>
{
entity.HasKey(e => new { e.LoginProvider, e.ProviderKey });
entity.HasIndex(e => e.UserId, "IX_AspNetUserLogins_UserId");
entity.HasOne(d => d.User).WithMany(p => p.AspNetUserLogins).HasForeignKey(d => d.UserId);
});
modelBuilder.Entity<AspNetUserToken>(entity =>
{
entity.HasKey(e => new { e.UserId, e.LoginProvider, e.Name });
entity.HasOne(d => d.User).WithMany(p => p.AspNetUserTokens).HasForeignKey(d => d.UserId);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
如果您的代码基于示例,则它们不会为 AspNetUserRole 等表使用显式实体,因此您不应尝试声明一个实体。这些表是用于多对多关系的连接表,并且在许多情况下是可选的。
要解决您的问题,请删除这些加入实体(例如 AspNetUserRole)的实体声明。您的映射已经适合连接表。
例如您的代码:
entity.HasMany(d => d.Roles).WithMany(p => p.Users)
.UsingEntity<Dictionary<string, object>>(
"AspNetUserRole",
r => r.HasOne<AspNetRole>().WithMany().HasForeignKey("RoleId"),
l => l.HasOne<AspNetUser>().WithMany().HasForeignKey("UserId"),
j =>
{
j.HasKey("UserId", "RoleId");
j.ToTable("AspNetUserRoles");
j.HasIndex(new[] { "RoleId" }, "IX_AspNetUserRoles_RoleId");
});
这是将 User 和 Role 之间的关系声明到 AspNetUserRoles 表,但将其映射为基本字典而不是显式实体类。不需要显式类,但您可以调整映射以使用它。在任何一种情况下,您都不需要为多对多连接表声明 DbSet,只需让 EF 找出您的实体应分别使用 User.Roles 和 Role.Users 的位置即可。