[英]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.