EF Core 2.0标识 – 添加导航属性

在EF Core 2.0中,默认情况下不包含身份导航属性,因此在升级后,我添加了它们。 因此,对于用户和角色之间的多对多关系,以及Role和RoleClaim之间的一对多关系,我添加了以下导航属性:

public class User : IdentityUser { [Required] public string Name { get; set; } public virtual ICollection<IdentityUserRole> Roles { get; set; } } public class Role : IdentityRole { [Required] public string Name { get; set; } public virtual ICollection<IdentityRoleClaim> Claims { get; set;} } 

令人惊讶的是,它为AspNetRoleClaims表和UserId1AspNetUserRoles表添加了一个额外的RoleId1键,并且所有获取查询实际上都使用新键而不是RoleIdUserId

我不知道为什么,没有这些有用的导航属性。 我想列出用户的角色。

所以我做了以下事情:

 public class ApplicationUser : IdentityUser { public virtual ICollection UserRoles { get; } = new List(); } public class ApplicationUserRole : IdentityUserRole { public virtual ApplicationUser User { get; set; } public virtual ApplicationRole Role { get; set; } } public class ApplicationRole : IdentityRole { public ApplicationRole(){ } public ApplicationRole(string roleName) : base(roleName) { } public virtual ICollection UserRoles { get; } = new List(); } 

这会创建导航,但会创建其他列,如RoleId1Discriminator 。 因此,我根据Add IdentityUser POCO Navigation Properties添加了以下内容。

 protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity() .HasMany(e => e.UserRoles) .WithOne() .HasForeignKey(e => e.UserId) .IsRequired() .OnDelete(DeleteBehavior.Cascade); builder.Entity() .HasOne(e => e.User) .WithMany(e => e.UserRoles) .HasForeignKey(e => e.UserId); builder.Entity() .HasOne(e => e.Role) .WithMany(e => e.UserRoles) .HasForeignKey(e => e.RoleId); } 

但我仍然有RoleId1Discriminator两个列。 之后,我用ApplicationDbContext,DI配置服务和DB种子中的新ApplicationRole类替换。

 public class ApplicationDbContext : IdentityDbContext , ApplicationUserRole, IdentityUserLogin, IdentityRoleClaim, IdentityUserToken> { ... } public void ConfigureServices(IServiceCollection services) { ... services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); ... } public DbInitializer( ApplicationDbContext context, UserManager userManager, RoleManager roleManager) { _context = context; _userManager = userManager; _roleManager = roleManager; } public async void Initialize() { _context.Database.EnsureCreated(); if (!_context.Roles.Any(r => r.Name == SharedConstants.Role.ADMINISTRATOR)) await _roleManager.CreateAsync(new ApplicationRole(SharedConstants.Role.ADMINISTRATOR)); } 

此外,我可以导航并获得角色的名字。

 ctx.Users.Select(e => new { e.Id, e.UserName, e.Email, e.PhoneNumber, Roles = e.UserRoles.Select(i => i.Role.Name).ToList() }).ToList(); 

我希望这能为您提供Claims导航属性的线索。

我遇到了同样的问题,这是解决方案。

您必须告诉Ef您将拥有OneToMany Relation的导航属性。

 protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); CreateUserModel(modelBuilder.Entity()); CreateRoleModel(modelBuilder.Entity()); } private void CreateRoleModel(EntityTypeBuilder entityTypeBuilder) { entityTypeBuilder.HasMany(role => role.UserRoles). WithOne(**e=> e.Role**). HasForeignKey(userRole => userRole.RoleId). IsRequired() .OnDelete(DeleteBehavior.Cascade); } private void CreateUserModel(EntityTypeBuilder entityTypeBuilder) { entityTypeBuilder.HasMany(user => user.UserRoles). WithOne(**e=>e.User**). HasForeignKey(userRole => userRole.UserId). IsRequired() .OnDelete(DeleteBehavior.Cascade); } 

您还可以在字符串中指定导航属性

 private void CreateRoleModel(EntityTypeBuilder entityTypeBuilder) { entityTypeBuilder.HasMany(role => role.UserRoles). WithOne(**"Role"**). HasForeignKey(userRole => userRole.RoleId). IsRequired() .OnDelete(DeleteBehavior.Cascade); } private void CreateUserModel(EntityTypeBuilder entityTypeBuilder) { entityTypeBuilder.HasMany(user => user.UserRoles). WithOne(**"User"**). HasForeignKey(userRole => userRole.UserId). IsRequired() .OnDelete(DeleteBehavior.Cascade); }