请参阅“将身份验证和身份迁移到 ASP.NET Core 2.0”的文档,特别是“Add IdentityUser POCO Navigation Properties”部分:
基础的实体框架 (EF) 核心导航属性
IdentityUser POCO(普通旧 CLR 对象)已被删除。如果你的
1.x 项目使用了这些属性,手动将它们添加回 2.0 项目:
/// <summary>
/// Navigation property for the roles this user belongs to.
/// </summary>
public virtual ICollection<IdentityUserRole<int>> Roles { get; } = new List<IdentityUserRole<int>>();
为防止在运行 EF Core 迁移时出现重复的外键,请添加
以下是您的IdentityDbContext 班级'OnModelCreating
方法(在base.OnModelCreating(); 调用之后):
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
builder.Entity<ApplicationUser>()
.HasMany(e => e.Roles)
.WithOne()
.HasForeignKey(e => e.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
编辑
以上内容仅满足通过IdentityUserRole 链接表访问对用户持有的角色ID 的任务。要通过导航属性访问角色实体本身,您需要添加另一个导航属性(这次针对从IdentityUserRole 继承的实体)。请参阅以下步骤:
- 修改
IdentityUser 实体上的Roles 导航属性,如下所示:
public virtual ICollection<UserRole> Roles { get; set; } = new List<UserRole>();
- 创建上面引用的
UserRole 实体:
public class UserRole : IdentityUserRole<int>
{
public virtual IdentityRole<int> Role { get; set; }
}
- 如下构造
UserRole 的映射:
builder.Entity<UserRole>()
.HasOne(e => e.Role)
.WithMany()
.HasForeignKey(e => e.RoleId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
- 然后您可以检索实体(填充导航属性),如下所示:
User user = context.Set<User>()
.Include(u => u.Roles)
.ThenInclude(r => r.Role)
.FirstOrDefault();
注意:
- 由于这是加载多对多关系的另一端,这可能会导致对数据库的多次调用(请参阅N+1 problem)。
- 当您创建一个继承自
IdentityUserRole 的新实体时,您需要迁移或重新创建数据库。
- 如果您想将此导航属性与
UserManager 或
RoleManager 您将需要使用长格式重载
AddUserStore() 和 AddRoleStore 在你的启动课程中,例如
services.AddIdentity<User, IdentityRole<int>>()
.AddUserStore<UserStore<User, IdentityRole<int>, SqlContext, int, IdentityUserClaim<int>, UserRole, IdentityUserLogin<int>, IdentityUserToken<int>, IdentityRoleClaim<int>>>()
.AddRoleStore<RoleStore<IdentityRole<int>, SqlContext, int, UserRole, IdentityRoleClaim<int>>>()
.AddDefaultTokenProviders();