我创建了一个用户,并在他身上附加了一个有多项声明的角色。问题是我没有看到使用Entity Framework Core和Identity集成访问它们的直接方法。这就是我理想的做法:
return _context.Users
.Include(u => u.Roles)
.ThenInclude(r => r.Role)
.ThenInclude(r => r.Claims)
但是没有Role属性,只有RoleId。所以我不能包含角色声明。当然,我得到一个单独的查询来获取声明甚至使用RoleManager:
var user = _context.Users.Single(x => x.Id == ...);
var role = _roleManager.Roles.Single(x => x.Id == user.Roles.ElementAt(0).RoleId);
var claims = _roleManager.GetClaimsAsync(role).Result;
但看起来效率低下甚至丑陋。应该有一种方法来进行单个查询。
我最后的希望是Controller.User属性(ClaimsIdentity)。我希望以某种方式巧妙地汇总所有角色的声明。但似乎并没有......
答案 0 :(得分:1)
您可以使用类似SQL的查询表达式,并获取用户的所有角色的所有声明:
var claims = from ur in _context.UserRoles
where ur.UserId == "user_id"
join r in _context.Roles on ur.RoleId equals r.Id
join rc in _context.RoleClaims on r.Id equals rc.RoleId
select rc;
答案 1 :(得分:1)
您可以添加导航属性。
public class Role : IdentityRole
{
public virtual ICollection<RoleClaim> RoleClaims { get; set; }
}
public class RoleClaim : IdentityRoleClaim<string>
{
public virtual Role Role { get; set; }
}
然后,您必须配置身份数据库上下文:
public class MyIdentityDbContext : IdentityDbContext<User, Role, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, RoleClaim, IdentityUserToken<string>>
用法:
await _context.Roles.Include(r => r.RoleClaims).ToListAsync();
最后,它生成以下查询:
SELECT `r`.`Id`, `r`.`ConcurrencyStamp`, `r`.`Name`, `r`.`NormalizedName`, `r0`.`Id`, `r0`.`ClaimType`, `r0`.`ClaimValue`, `r0`.`RoleId`
FROM `roles` AS `r`
LEFT JOIN `role_claims` AS `r0` ON `r`.`Id` = `r0`.`RoleId`
ORDER BY `r`.`Id`, `r0`.`Id`
答案 2 :(得分:-1)
确保正确添加角色和声明。以下是我如何创建用户并添加声明和角色的示例。
private async Task<IdentityResult> CreateNewUser(ApplicationUser user, string password = null){
//_roleManger is of type RoleManager<IdentityRole>
// _userManger is of type UserManager<ApplicationUser>
//and both are injected in to the controller.
if (!await _roleManger.RoleExistsAsync("SomeRole")){
await _roleManger.CreateAsync(new IdentityRole("SomeRole"));
}
var result = password != null ? await _userManager.CreateAsync(user, password) : await _userManager.CreateAsync(user);
if(result.Succeeded) {
await _userManager.AddToRoleAsync(user, "SomeRole");
await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Name, user.Email));
}
return result;
}
然后,您可以使用_userManager
获取声明。 This is how我使用_userManager
获取当前用户。然后你可以这样打电话:
var claims = await _userManager.GetClaimsAsync(user);