C# LINQ IdentityContext 多组加入
C# LINQ IdentityContext Multi Group Join
我有这个 LINQ:
var users = _ctx.Users
.AsEnumerable() // or "InvalidOperationException: This may indicate either a bug or a limitation in EF Core"
.GroupJoin(_ctx.UserClaims, u => u.Id, c => c.UserId, (user, claims) => new { user, claims })
.GroupJoin(_ctx.UserRoles, uc => uc.user.Id, r => r.UserId, (uc, roles) => new { uc.user, uc.claims, roles })
.ToList()
.Select(ucr => new UserDto
{
Id = ucr.user.Id,
UserName = ucr.user.UserName,
FirstName = ucr.user.FirstName,
LastName = ucr.user.LastName,
LastLogin = ucr.user.LastLogin,
LockoutEnd = ucr.user.LockoutEnd,
LockoutEnabled = ucr.user.LockoutEnabled,
Roles = ucr.roles.Select(x => x.RoleId).Distinct().ToList(), // Here i would like the Role Name from the Roles Table by the UserRoles
Scopes = ucr.claims.Select(x => x.ToClaim()).Where(x => x.Type.Equals(Shared.Scopes.Key)).Select(x => x.Value).ToList(),
Claims = ucr.claims.Select(x => x.ToClaim()).Where(x => !x.Type.Equals(Shared.Scopes.Key)).ToList(),
Enabled = ucr.user.Enabled
}
).ToList();
这工作得很好,但我想获取用户的实际角色,而不仅仅是从 UserRoles 中获取用户到角色的映射
我尝试添加一个额外的 GroupJoin:
.GroupJoin(_ctx.Roles, ucr => ucr.roles.Id, r => r.Id, (ucr, r) => new { u, r })
但是因为 roles
是一个列表,所以我得到一个错误:
'IEnumerable<IdentityUserRole>' does not contain a definition
for 'Id' and no accessible extension method 'Id' accepting a first
argument of type 'IEnumerable<IdentityUserRole>'
关于如何获得实际角色列表的任何想法?
我使用的是默认身份 类 而不是 ApplicationUser
public class ApplicationUser : IdentityUser
{
/// <summary>
/// First Name
/// </summary>
[Display(Name = "First Name")]
public string FirstName { get; set; }
/// <summary>
/// Last Name
/// </summary>
[Display(Name = "Last Name")]
public string LastName { get; set; }
/// <summary>
/// Profile Picture
/// </summary>
public byte[] ProfilePicture { get; set; }
/// <summary>
/// Enabled
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Last Login
/// </summary>
[Display(Name = "Last Login")]
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, NullDisplayText = "N/A", DataFormatString = "{0:yyyy-MM-dd HH:mm}")]
public DateTime? LastLogin { get; set; } = null;
/// <summary>
/// Display Name
/// </summary>
[NotMapped]
public string DisplayName => $"{FirstName} {LastName}";
}
和 UserDto
public class UserDto
{
public UserDto()
{
Id = Guid.NewGuid().ToString();
ConcurrencyStamp = Guid.NewGuid().ToString();
}
public string Id { get; set; }
public string UserName { get; set; }
public string NormalizedUserName => UserName.ToUpper();
public string Email => UserName;
public string NormalizedEmail => Email.ToUpper();
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string ConcurrencyStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public byte[] ProfilePicture { get; set; }
public DateTime? LastLogin { get; set; }
public bool Enabled { get; set; }
public List<string> Roles { get; set; }
public List<Claim> Claims { get; set; }
public List<string> Scopes { get; set; }
}
加入UserRoles
和Roles
,所以使用群组加入。
var users = _ctx.Users
.AsEnumerable()
.GroupJoin(_ctx.UserClaims, u => u.Id, c => c.UserId, (user, claims) => new { user, claims })
.GroupJoin(
_ctx.UserRoles.Join(_ctx.Roles, ur => ur.RoleId, r => r.Id, (userRole, role) => new { userRole, role }),
uc => uc.user.Id, r => r.userRole.UserId,
(uc, roles) => new { uc.user, uc.claims, roles})
.Select(ucr => new
{
Id = ucr.user.Id,
UserName = ucr.user.UserName,
FirstName = ucr.user.FirstName,
LastName = ucr.user.LastName,
LastLogin = ucr.user.LastLogin,
LockoutEnd = ucr.user.LockoutEnd,
LockoutEnabled = ucr.user.LockoutEnabled,
Roles = ucr.roles.Select(x => x.role.Name).Distinct().ToList(),
Scopes = ucr.claims.Select(x => x.ToClaim()).Where(x => x.Type.Equals(Shared.Scopes.Key)).Select(x => x.Value).ToList(),
Claims = ucr.claims.Select(x => x.ToClaim()).Where(x => !x.Type.Equals(Shared.Scopes.Key)).ToList(),
Enabled = ucr.user.Enabled
}
).ToList();
我有这个 LINQ:
var users = _ctx.Users
.AsEnumerable() // or "InvalidOperationException: This may indicate either a bug or a limitation in EF Core"
.GroupJoin(_ctx.UserClaims, u => u.Id, c => c.UserId, (user, claims) => new { user, claims })
.GroupJoin(_ctx.UserRoles, uc => uc.user.Id, r => r.UserId, (uc, roles) => new { uc.user, uc.claims, roles })
.ToList()
.Select(ucr => new UserDto
{
Id = ucr.user.Id,
UserName = ucr.user.UserName,
FirstName = ucr.user.FirstName,
LastName = ucr.user.LastName,
LastLogin = ucr.user.LastLogin,
LockoutEnd = ucr.user.LockoutEnd,
LockoutEnabled = ucr.user.LockoutEnabled,
Roles = ucr.roles.Select(x => x.RoleId).Distinct().ToList(), // Here i would like the Role Name from the Roles Table by the UserRoles
Scopes = ucr.claims.Select(x => x.ToClaim()).Where(x => x.Type.Equals(Shared.Scopes.Key)).Select(x => x.Value).ToList(),
Claims = ucr.claims.Select(x => x.ToClaim()).Where(x => !x.Type.Equals(Shared.Scopes.Key)).ToList(),
Enabled = ucr.user.Enabled
}
).ToList();
这工作得很好,但我想获取用户的实际角色,而不仅仅是从 UserRoles 中获取用户到角色的映射
我尝试添加一个额外的 GroupJoin:
.GroupJoin(_ctx.Roles, ucr => ucr.roles.Id, r => r.Id, (ucr, r) => new { u, r })
但是因为 roles
是一个列表,所以我得到一个错误:
'IEnumerable<IdentityUserRole>' does not contain a definition for 'Id' and no accessible extension method 'Id' accepting a first argument of type 'IEnumerable<IdentityUserRole>'
关于如何获得实际角色列表的任何想法?
我使用的是默认身份 类 而不是 ApplicationUser
public class ApplicationUser : IdentityUser
{
/// <summary>
/// First Name
/// </summary>
[Display(Name = "First Name")]
public string FirstName { get; set; }
/// <summary>
/// Last Name
/// </summary>
[Display(Name = "Last Name")]
public string LastName { get; set; }
/// <summary>
/// Profile Picture
/// </summary>
public byte[] ProfilePicture { get; set; }
/// <summary>
/// Enabled
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Last Login
/// </summary>
[Display(Name = "Last Login")]
[DataType(DataType.DateTime)]
[DisplayFormat(ApplyFormatInEditMode = true, NullDisplayText = "N/A", DataFormatString = "{0:yyyy-MM-dd HH:mm}")]
public DateTime? LastLogin { get; set; } = null;
/// <summary>
/// Display Name
/// </summary>
[NotMapped]
public string DisplayName => $"{FirstName} {LastName}";
}
和 UserDto
public class UserDto
{
public UserDto()
{
Id = Guid.NewGuid().ToString();
ConcurrencyStamp = Guid.NewGuid().ToString();
}
public string Id { get; set; }
public string UserName { get; set; }
public string NormalizedUserName => UserName.ToUpper();
public string Email => UserName;
public string NormalizedEmail => Email.ToUpper();
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string ConcurrencyStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public byte[] ProfilePicture { get; set; }
public DateTime? LastLogin { get; set; }
public bool Enabled { get; set; }
public List<string> Roles { get; set; }
public List<Claim> Claims { get; set; }
public List<string> Scopes { get; set; }
}
加入UserRoles
和Roles
,所以使用群组加入。
var users = _ctx.Users
.AsEnumerable()
.GroupJoin(_ctx.UserClaims, u => u.Id, c => c.UserId, (user, claims) => new { user, claims })
.GroupJoin(
_ctx.UserRoles.Join(_ctx.Roles, ur => ur.RoleId, r => r.Id, (userRole, role) => new { userRole, role }),
uc => uc.user.Id, r => r.userRole.UserId,
(uc, roles) => new { uc.user, uc.claims, roles})
.Select(ucr => new
{
Id = ucr.user.Id,
UserName = ucr.user.UserName,
FirstName = ucr.user.FirstName,
LastName = ucr.user.LastName,
LastLogin = ucr.user.LastLogin,
LockoutEnd = ucr.user.LockoutEnd,
LockoutEnabled = ucr.user.LockoutEnabled,
Roles = ucr.roles.Select(x => x.role.Name).Distinct().ToList(),
Scopes = ucr.claims.Select(x => x.ToClaim()).Where(x => x.Type.Equals(Shared.Scopes.Key)).Select(x => x.Value).ToList(),
Claims = ucr.claims.Select(x => x.ToClaim()).Where(x => !x.Type.Equals(Shared.Scopes.Key)).ToList(),
Enabled = ucr.user.Enabled
}
).ToList();