首页 > 解决方案 > Projection with asynchronous programming

问题描述

I'm introducing asynchronous programming to my existing code base and having some trouble with calling Select() on the result of GetStudents() - the error message received is as follows "Task<List<ApplicationUser>> does not contain a defintion for Select". I think it'll be due to incorrect syntax, but any guidance would be appreciated - thanks.

   public async Task<List<ApplicationUser>> GetStudents()
    {
        return await Task.Run(() => _context.Users.ToList());
    }


    public async Task<StudentIndexViewModel> CreateStudentRegisterViewModel()
    {
        var model = new StudentIndexViewModel();
        var students = await _studentRepo.GetStudents().
            Select(x => new StudentViewModel
            {
                Forename = x.Forename,
                Surname = x.Surname
            }).ToListAsync();

        model.Students = students;

        return model;
    }

标签: c#asp.net-mvcentity-framework

解决方案


如前所述,错误来自尝试调用Selecta Task<T>,这是无效的。然而,问题远不止于此。该代码目前正在从数据库中获取整个表,只是为了从结果in-memory中获取一些值。这在数据库和应用程序服务器中都浪费了处理时间。
不仅如此,使用线程池线程只是为了等待 I/O 操作也是一种浪费。

总的来说,代码应该是这样的。

public async Task<List<ApplicationUser>> GetApplicationUsersAsync()
{
    // use Entity Framework properly with ToListAsync
    // this returns the entire table
    return await _context.Users.ToListAsync();
}

public async Task<List<StudentViewModel>> GetStudentsAsync()
{
    // use Entity Framework properly with ToListAsync
    return await _context.Users
        // this only returns the 2 needed properties
        .Select(x => new StudentViewModel
        {
            Forename = x.Forename,
            Surname = x.Surname
        })
        .ToListAsync();
}


public async Task<StudentIndexViewModel> CreateStudentRegisterViewModel()
{
    var model = new StudentIndexViewModel();
    model.Students = await _studentRepo.GetStudentsAsync();

    return model;
}

推荐阅读