Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一个查询中获得具有角色的用户?_C#_Asp.net Core_Entity Framework Core_Asp.net Core Identity - Fatal编程技术网

C# 如何在一个查询中获得具有角色的用户?

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

我已按如下所述设置了身份模型:

因此,我的每个用户类都有一个角色集合,通过UserRole“包装器”。 所有实体关系都已设置

当我查询我的用户时,我会得到每个用户的所有角色(这里使用延迟加载,但“包含”没有区别):

但在检查EF Core创建的日志时,我发现每个用户都有另一个查询来获取角色:

[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();