解决方法中的IQueryable和Async

时间:2019-08-23 07:33:22

标签: c# linq generics asp.net-core .net-core

我正在尝试结合异步原理并正确实施。 在下面的代码中,departmentRepository.GetAll返回IQueryable。之后,GetPage(1,3)返回IEnumerable。只是好奇,根据Intellisense,新的代码行是否有意义。

原始代码:

应用服务代码:

public async Task<IEnumerable<DepartmentDto>> GetAllDepartments()
{
    var departments = await departmentRepository.GetAll();
    Paged<Department> departmentPaged = new Paged<Department>(departments);
    var departments2 = departmentPaged.GetPage(1, 3);
    var departmentDto = mapper.Map<IEnumerable<Department>, IEnumerable<DepartmentDto>>(departments2);
    return  departmentDto;
}

第一行等待departmentRepository.GetAll()给我一个错误。

  

IQueryable不包含GetAwaiter的定义和不可访问的扩展方法Getawaiter`

因此,Intellisense建议更改为

var departments = await departmentRepository.GetAll().ToListAsync();

更改后,第二个错误将在var部门2中弹出= departmentPaged.GetPage(1、3);

  

无法转换为System.Linq.IQueryable的System.Collections.Generic.List。

因此,Intellisense建议更改为

Paged<Department> departmentPaged = new Paged<Department>(departments.AsQueryable());

所以新代码如下:

这有意义吗,是回旋处,还是什么好方法?

public async Task<IEnumerable<DepartmentDto>> GetAllDepartments()
{
    var departments = await departmentRepository.GetAll().ToListAsync();
    Paged<Department> departmentPaged = new Paged<Department>(departments.AsQueryable());
    var departments2 = departmentPaged.GetPage(1, 3);
    var departmentDto = mapper.Map<IEnumerable<Department>, IEnumerable<DepartmentDto>>(departments2);
    return  departmentDto;
    }

也在对此进行研究:IQueryable does not contain definition for GetAwaiter

其他参考代码:

基本存储库和其他选项(公司的架构师需要通用存储库,而不是我的电话):

    public IQueryable<T> GetAll()
    {
        return All;
    }
    public List<T> GetAllList()
    {
        return All.ToList();
    }

    public List<T> GetAllList(Expression<Func<T, bool>> predicate)
    {
        return All.Where(predicate).ToList();
    }

    public async Task<List<T>> GetAllListAsync()
    {
        return await All.ToListAsync();
    }

分页方法:

    public IEnumerable<T> GetPage(int index, int limit)
    {
        return source.Skip((index - 1) * limit)
            .Take(limit);
    }

1 个答案:

答案 0 :(得分:0)

尽管我有时会认为在通用存储库接口中公开IQueryable<T>是完全失败的,但我发现您不能反对这一点。

好像您可以将其重写为:

public IEnumerable<DepartmentDto> GetAllDepartments()
{
    var departmentPaged = new Paged<Department>(departmentRepository.GetAll());
    return mapper.Map<IEnumerable<Department>, IEnumerable<DepartmentDto>>(departmentPaged.GetPage(1, 3));
}

这不涉及异步代码。

如果您仍然想强制将返回类型包装在任务中,则可以执行以下操作:

public Task<IEnumerable<DepartmentDto>> GetAllDepartments()
{
    var departmentPaged = new Paged<Department>(departmentRepository.GetAll());
    return Task.FromResult(mapper.Map<IEnumerable<Department>, IEnumerable<DepartmentDto>>(departmentPaged.GetPage(1, 3)));
}