2017-08-24 292 views
1

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

public class User : IdentityUser 
{ 
    [Required] 
    public string Name { get; set; } 

    public virtual ICollection<IdentityUserRole<string>> Roles { get; set; } 
} 

public class Role : IdentityRole 
{ 
    [Required] 
    public string Name { get; set; } 

    public virtual ICollection<IdentityRoleClaim<string>> Claims { get; set;} 
} 

令人惊讶的是增加了一个额外RoleId1关键AspNetRoleClaims表和UserId1AspNetUserRoles表和所有的GET查询实际使用新的密钥,而不是RoleIdUserId同样存在。

+0

一看便知在此线程https://stackoverflow.com/a/47772406/82197 – leen3o

回答

2

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

所以我做了如下:

public class ApplicationUser : IdentityUser 
{ 
    public virtual ICollection<ApplicationUserRole> UserRoles { get; } = new List<ApplicationUserRole>(); 
} 

public class ApplicationUserRole : IdentityUserRole<string> 
{ 
    public virtual ApplicationUser User { get; set; } 
    public virtual ApplicationRole Role { get; set; } 
} 

public class ApplicationRole : IdentityRole<string> 
{ 
    public ApplicationRole(){ } 

    public ApplicationRole(string roleName) 
     : base(roleName) 
    { 
    } 

    public virtual ICollection<ApplicationUserRole> UserRoles { get; } = new List<ApplicationUserRole>(); 
} 

这就造成了导航,但它会建立像RoleId1Discriminator附加列。所以,我根据Add IdentityUser POCO Navigation Properties添加了以下内容。

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

    builder.Entity<ApplicationUser>() 
     .HasMany(e => e.UserRoles) 
     .WithOne() 
     .HasForeignKey(e => e.UserId) 
     .IsRequired() 
     .OnDelete(DeleteBehavior.Cascade); 

    builder.Entity<ApplicationUserRole>() 
     .HasOne(e => e.User) 
     .WithMany(e => e.UserRoles) 
     .HasForeignKey(e => e.UserId); 

    builder.Entity<ApplicationUserRole>() 
     .HasOne(e => e.Role) 
     .WithMany(e => e.UserRoles) 
     .HasForeignKey(e => e.RoleId); 
} 

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

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string> 
    , ApplicationUserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>> 
{ 
    ... 
} 

public void ConfigureServices(IServiceCollection services) 
{ 
    ... 
    services.AddIdentity<ApplicationUser, ApplicationRole>() 
      .AddEntityFrameworkStores<ApplicationDbContext>() 
      .AddDefaultTokenProviders(); 
    ... 
} 

public DbInitializer(
     ApplicationDbContext context, 
     UserManager<ApplicationUser> userManager, 
     RoleManager<ApplicationRole> 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导航属性。

+0

感谢非常完整的答案。我只是碰到了这个,跟着你的建议,现在走了! –