ASP.Net 核心:使用 LinQ Select 方法获取用户角色
ASP.Net Core: Get User Roles with LinQ Select method
当 select 用户角色在 Asp.Net Core 中使用 LinQ 时,我遇到了问题。这是我的功能:
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();
}
我想在 Select 方法中使用 async
关键字以便使用:await userManager.GetRolesAsync(x)
但 intellisense 警告我:
Async lambda expressions cannot be converted to expression trees.
感谢您的帮助^^
我可以建议您 2 个解决方案。
第一个是这样划分两个步骤。首先,获取用户,然后获取角色。我认为问题可能在于 EF 无法将异步代码转换为表达式树,然后将其转换为 SQL。因此,通过单独进行确保您的第二步是 linq to object request(而不是 linq to SQL)。此解决方案的问题是您对数据库发出了太多请求。就是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)
})
}
因此,这为我们指明了第二种方法。它直接向 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
};
此解决方案只需发出一个数据库请求并获取您想要的所有数据。
当 select 用户角色在 Asp.Net Core 中使用 LinQ 时,我遇到了问题。这是我的功能:
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();
}
我想在 Select 方法中使用 async
关键字以便使用:await userManager.GetRolesAsync(x)
但 intellisense 警告我:
Async lambda expressions cannot be converted to expression trees.
感谢您的帮助^^
我可以建议您 2 个解决方案。 第一个是这样划分两个步骤。首先,获取用户,然后获取角色。我认为问题可能在于 EF 无法将异步代码转换为表达式树,然后将其转换为 SQL。因此,通过单独进行确保您的第二步是 linq to object request(而不是 linq to SQL)。此解决方案的问题是您对数据库发出了太多请求。就是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)
})
}
因此,这为我们指明了第二种方法。它直接向 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
};
此解决方案只需发出一个数据库请求并获取您想要的所有数据。