简体   繁体   English

ASP.Net Core:使用 LinQ Select 方法获取用户角色

[英]ASP.Net Core: Get User Roles with LinQ Select method

I had a problem when select user roles with LinQ in Asp.Net Core.我在 Asp.Net Core 中使用 LinQ 的 select 用户角色时遇到问题。 This is my function:这是我的 function:

public async Task<ApiResult<PagedResult<UserViewModel>>> GetUserPaging(PagingRequestBase request)
{
    if(request==null) return new ApiErrorResult<PagedResult<UserViewModel>>("Invalid request");
    var query= await userManager.Users.Skip((request.PageIndex-1)*request.PageSize)
    .Take(request.PageSize)
    .Select(async x => new UserViewModel{
        UserName=x.UserName,
        Dob=x.Dob,
        Email=x.Email,
        FirstName=x.FirstName,
        LastName=x.LastName,
        Roles=await userManager.GetRolesAsync(x)
    }).ToListAsync();
}

I want to use async keyword inside Select method in order to use: await userManager.GetRolesAsync(x) but intellisense warning me:我想在 Select 方法中使用async关键字,以便使用: await userManager.GetRolesAsync(x)但智能感知警告我:

Async lambda expressions cannot be converted to expression trees.异步 lambda 表达式无法转换为表达式树。

Thanks for yours help ^^谢谢你的帮助^^

I can suggest you 2 solutions.我可以建议你 2 个解决方案。 The first one is so dividing the two steps.第一个是如此划分两个步骤。 First, get the users, and then get the roles.首先,获取用户,然后获取角色。 I think the problem could be that EF can't convert the async code to the expression tree and then convert it to SQL.我认为问题可能是EF无法将异步代码转换为表达式树,然后将其转换为SQL。 So making it by separate ensures you that the second step is linq to object request (not linq to SQL).因此,单独进行可确保您第二步是 linq 到 object 请求(不是 linq 到 SQL)。 The problem with this solution is that you are making to much requests to the Database.此解决方案的问题是您对数据库提出了很多请求。 It is the N + 1 problem.这是N + 1问题。

public async Task<ApiResult<PagedResult<UserViewModel>>> GetUserPaging(PagingRequestBase request)
{
    if(request==null) return new ApiErrorResult<PagedResult<UserViewModel>>("Invalid request");
    var users = await userManager.Users.Skip((request.PageIndex-1)*request.PageSize)
    .Take(request.PageSize)
    .ToListAsync();

    var query = users.Select(async x => new UserViewModel{
        UserName=x.UserName,
        Dob=x.Dob,
        Email=x.Email,
        FirstName=x.FirstName,
        LastName=x.LastName,
        Roles=await userManager.GetRolesAsync(x)
    })
}

So, this points us to the second approach.因此,这为我们指明了第二种方法。 And it is making the request directly to the EF Database Context, and making the joining explicitly:它直接向 EF 数据库上下文发出请求,并显式地加入:

            YourfDbContext t = null;  // this is only for pointing it

            var x = from usr in t.Users 
                    join userRole in t.UserRoles on usr.Id equals userRole.UserId 
                    join role in t.Roles on userRole.RoleId equals role.Id into roles
                    select new {
                        User = usr,
                        Roles = roles
                    };

This solution only makes one DB request and get all the data you want.此解决方案仅发出一个数据库请求并获取您想要的所有数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM