C# 如何使用异步一直到顶部

C# 如何使用异步一直到顶部,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我有一个通用存储库,它有异步方法FindAsync: public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class { private dynamic _context; private DbSet<TEntity> _dbSet; protected DbContext Context { get

我有一个通用存储库,它有异步方法
FindAsync

public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private dynamic _context;
    private DbSet<TEntity> _dbSet;

    protected DbContext Context
    {
        get
        {
            if (_context == null)
            {
                _context = DataContextFactory.GetDataContext();
            }

            return _context;
        }
    }

    protected DbSet<TEntity> DBSet
    {
        get
        {
            if (_dbSet == null)
            {
                _dbSet = Context.Set<TEntity>();
            }

            return _dbSet;
        }
    }

    public virtual IQueryable<TEntity> GetQuery(Expression<Func<TEntity, bool>> predicate = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
    {
        IQueryable<TEntity> qry = DBSet;

        if (predicate != null)
        {
            qry = qry.Where(predicate);
        }

        if (orderExpression != null)
        {
            return orderExpression(qry);
        }

        return qry;
    }

    public virtual IQueryable<T> GetQuery<T>(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderExpression = null) where T : class
    {
        DbSet<T> dbSet = Context.Set<T>();
        IQueryable<T> qry = dbSet;

        if (predicate != null)
        {
            qry = qry.Where(predicate);
        }

        if (orderExpression != null)
        {
            return orderExpression(qry);
        }

        return qry;
    }

    public virtual async Task<IEnumerable<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderExpression = null)
    {
        return await GetQuery(predicate, orderExpression).ToListAsync();
    }

    public virtual async Task<IEnumerable<T>> FindAsync<T>(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IOrderedQueryable<T>> orderExpression = null) where T : class
    {
        return await GetQuery<T>(predicate, orderExpression).ToListAsync();
    }
}
我遇到的问题是,当我调用
await\u repo.FindAsync(p=>p.Id==Id).Result.SingleOrDefaultAsync()时

上面说

IEnumerable客户不包含SingleOrDefaultAsync的定义


有人知道我错过了什么吗?

我想这是对如何使用的误解

在返回
任务
类型的
async
方法上使用
await
操作符暂停该方法的执行,直到等待的任务完成

然后将返回值分配给变量

public async Task<Customer> GetByIdAsync(Guid id)
{
    // Call the async method to get the task returning the customers
    Task<IEnumerable<Customer>> customersTask = _repo.FindAsync(p => p.Id == id);

    // Wait for the customers to be fetched
    IEnumerable<Customer> customers = await customersTask;

    // Get the customer
    return customers.SingleOrDefault();
}
公共异步任务GetByIdAsync(Guid id)
{
//调用async方法以获取返回客户的任务
任务客户任务=_repo.FindAsync(p=>p.Id==Id);
//等待客户被取回
IEnumerable customers=等待客户任务;
//抓住顾客
return customers.SingleOrDefault();
}
这类似于:

public async Task<Customer> GetByIdAsync(Guid id)
{
    var customers = await _repo.FindAsync(p => p.Id == id);
    return customers.SingleOrDefault();
}
公共异步任务GetByIdAsync(Guid id)
{
var客户=等待_repo.FindAsync(p=>p.Id==Id);
return customers.SingleOrDefault();
}

我认为对如何使用存在误解

在返回
任务
类型的
async
方法上使用
await
操作符暂停该方法的执行,直到等待的任务完成

然后将返回值分配给变量

public async Task<Customer> GetByIdAsync(Guid id)
{
    // Call the async method to get the task returning the customers
    Task<IEnumerable<Customer>> customersTask = _repo.FindAsync(p => p.Id == id);

    // Wait for the customers to be fetched
    IEnumerable<Customer> customers = await customersTask;

    // Get the customer
    return customers.SingleOrDefault();
}
公共异步任务GetByIdAsync(Guid id)
{
//调用async方法以获取返回客户的任务
任务客户任务=_repo.FindAsync(p=>p.Id==Id);
//等待客户被取回
IEnumerable customers=等待客户任务;
//抓住顾客
return customers.SingleOrDefault();
}
这类似于:

public async Task<Customer> GetByIdAsync(Guid id)
{
    var customers = await _repo.FindAsync(p => p.Id == id);
    return customers.SingleOrDefault();
}
公共异步任务GetByIdAsync(Guid id)
{
var客户=等待_repo.FindAsync(p=>p.Id==Id);
return customers.SingleOrDefault();
}

这是您的问题之一。另一种情况是,您将阻塞调用
.Result
异步/await
调用混合在一起

/// <summary>
/// Gets customer by id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Customer> GetByIdAsync(Guid id) {
    var records = await _repo.FindAsync(p => p.Id == id);
    return records.AsQueryable().SingleOrDefaultAsync();
}
//
///按id获取客户
/// 
/// 
/// 
公共异步任务GetByIdAsync(Guid id){
var记录=等待_repo.FindAsync(p=>p.Id==Id);
返回记录.AsQueryable().SingleOrDefaultAsync();
}

还要确保您有正确的参考资料,这是您的问题之一。另一种情况是,您将阻塞调用
.Result
异步/await
调用混合在一起

/// <summary>
/// Gets customer by id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Customer> GetByIdAsync(Guid id) {
    var records = await _repo.FindAsync(p => p.Id == id);
    return records.AsQueryable().SingleOrDefaultAsync();
}
//
///按id获取客户
/// 
/// 
/// 
公共异步任务GetByIdAsync(Guid id){
var记录=等待_repo.FindAsync(p=>p.Id==Id);
返回记录.AsQueryable().SingleOrDefaultAsync();
}
还要确保您有正确的参考资料

添加 使用System.Data.Entity 转到CustomerRepository.cs顶部的using语句

将FindAsync的returntype更改为ReturniQueryable

见进一步指南

另外,不要像后面的评论建议的那样,将阻塞调用(.Result)与异步/等待混合使用。

Add 使用System.Data.Entity 转到CustomerRepository.cs顶部的using语句

将FindAsync的returntype更改为ReturniQueryable

见进一步指南


另外,不要像后面的评论所建议的那样,将阻塞调用(.Result)与异步/等待混合使用。

这是您的问题之一。另一种情况是将阻塞调用
.Result
async/await
calls混合使用。FindAsync从通用存储库返回IEnumerable。现在在我的客户存储库中,我希望方法GetByIdAsync调用FindAsync,并且应该只返回与谓词匹配的单个项,这就是我使用的原因。结果检查您的using语句,是否缺少对System.Data.Entity的引用?@AndrewReyes这不是使用
结果
的原因。您应该
等待
任务
编写使用结果的代码。这是您的问题之一。另一种情况是将阻塞调用
.Result
async/await
calls混合使用。FindAsync从通用存储库返回IEnumerable。现在在我的客户存储库中,我希望方法GetByIdAsync调用FindAsync,并且应该只返回与谓词匹配的单个项,这就是我使用的原因。结果检查您的using语句,是否缺少对System.Data.Entity的引用?@AndrewReyes这不是使用
结果
的原因。您应该
等待
任务
来编写使用结果的代码。除非FindAsync方法返回IQueryable,否则它不会工作,但在我的例子中,它返回IEnumerableh是的,我不小心引用了错误的方法签名。请稍后参阅edit。它不会工作,除非FindAsync方法返回IQueryable,但在我的例子中,它返回IEnumerableOh是的,我不小心引用了错误的方法签名。请稍后参阅编辑。@AndrewReyes如第一个示例所示,您将有一个普通的
IEnumerable
,因此不需要异步方法。@AndrewReyes如第一个示例所示,您将有一个普通的
IEnumerable
,因此不需要异步方法。