C# 如何在一个查询中获得具有角色的用户?
我已按如下所述设置了身份模型: 因此,我的每个用户类都有一个角色集合,通过UserRole“包装器”。 所有实体关系都已设置 当我查询我的用户时,我会得到每个用户的所有角色(这里使用延迟加载,但“包含”没有区别): 但在检查EF Core创建的日志时,我发现每个用户都有另一个查询来获取角色:C# 如何在一个查询中获得具有角色的用户?,c#,asp.net-core,entity-framework-core,asp.net-core-identity,C#,Asp.net Core,Entity Framework Core,Asp.net Core Identity,我已按如下所述设置了身份模型: 因此,我的每个用户类都有一个角色集合,通过UserRole“包装器”。 所有实体关系都已设置 当我查询我的用户时,我会得到每个用户的所有角色(这里使用延迟加载,但“包含”没有区别): 但在检查EF Core创建的日志时,我发现每个用户都有另一个查询来获取角色: [Parameters=[@_outer_Id='d550f61b-ed3d-4d90-8e7b-31552de50d3b' (Size = 450)], CommandType='"Text"', Co
[Parameters=[@_outer_Id='d550f61b-ed3d-4d90-8e7b-31552de50d3b' (Size = 450)], CommandType='"Text"', CommandTimeout='30']
SELECT [r].[RoleId] AS [Id], [r.Role].[Name], [r.Role].[DisplayName]
FROM [AspNetUserRoles] AS [r]
INNER JOIN [AspNetRoles] AS [r.Role] ON [r].[RoleId] = [r.Role].[Id]
WHERE ([r].[Discriminator] = N'UserRole') AND (@_outer_Id = [r].[UserId])
这会在数据库中的每个用户Id上重复
如何只使用一个查询来获得结果
以防万一,我的模型:
public class User : IdentityUser
{
public virtual ICollection<UserRole> UserRoles { get; set; }
}
public class UserRole : IdentityUserRole<string>
{
public virtual User User { get; set; }
public virtual Role Role { get; set; }
}
public class Role : IdentityRole
{
public virtual ICollection<UserRole> UserRoles { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne(e => e.User)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
modelBuilder.Entity<Role>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne(e => e.Role)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
});
}
公共类用户:IdentityUser
{
公共虚拟ICollection用户角色{get;set;}
}
公共类用户角色:IdentityUserRole
{
公共虚拟用户用户{get;set;}
公共虚拟角色{get;set;}
}
公共类角色:IdentityRole
{
公共虚拟ICollection用户角色{get;set;}
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity(b=>
{
b、 HasMany(e=>e.UserRoles)
.WithOne(e=>e.User)
.HasForeignKey(ur=>ur.UserId)
.IsRequired();
});
modelBuilder.Entity(b=>
{
b、 HasMany(e=>e.UserRoles)
.WithOne(e=>e.Role)
.HasForeignKey(ur=>ur.RoleId)
.IsRequired();
});
}
看起来您启用了延迟加载。EF从不自动连接相关表,您必须以某种方式指示它这样做。在延迟加载的情况下,这是通过访问导航属性的getter实现的。getter被EF覆盖以从对象缓存中提取相关实体,如果在那里找不到它们,则发出查询以检索它们(因此称为“lazy”)。显然,您只是在迭代用户并访问每个用户的UserRoles
成员,这会导致为每个用户发出单独的查询
您要做的是立即加载关系。您可以通过Include
(以及子关系的然后Include
)执行此操作。换言之:
var users = await _userManager.Users
.Include(x => x.UserRoles)
.ThenInclude(x => x.Role)
.AsNoTracking()
.ToListAsync();
使用
Include()
显示您的查询。谢谢。我已经完全禁用了延迟加载,现在一切都很好。
var users = await _userManager.Users
.Include(x => x.UserRoles)
.ThenInclude(x => x.Role)
.AsNoTracking()
.ToListAsync();