2017-08-24 294 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

感謝非常完整的答案。我只是碰到了這個,跟着你的建議,現在走了! –