我有通用存储库,其中包含异步方法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();
}
}
然后我创建了一个CustomerRepository
,它从通用仓库调用FindAsync
:
public class CustomerRepository
{
private readonly IRepository<Customer> _repo;
/// <summary>
/// Hookup dependencies
/// </summary>
/// <param name="repo"></param>
public CustomerRepository(IRepository<Customer> repo)
{
_repo = repo;
//Disable entity proxy creation and lazy loading.
_repo.LazyLoadingEnabled(false);
}
/// <summary>
/// Gets customer by id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Customer> GetByIdAsync(Guid id)
{
return await _repo.FindAsync(p => p.Id == id).Result.SingleOrDefaultAsync();
}
}
我遇到的问题是当我致电await _repo.FindAsync(p => p.Id == id).Result.SingleOrDefaultAsync();
它说
IEnumerable Customer不包含SingleOrDefaultAsync的定义。
任何人都知道我错过了什么?
答案 0 :(得分:4)
我认为对await
的使用方式存在误解。
在await
方法上使用async
运算符,返回Task
类型以暂停执行方法,直到等待的任务完成。
然后将返回值赋给变量。
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();
}
这类似于:
public async Task<Customer> GetByIdAsync(Guid id)
{
var customers = await _repo.FindAsync(p => p.Id == id);
return customers.SingleOrDefault();
}
答案 1 :(得分:2)
这是你的一个问题。另一个是你将阻止通话.Result
与async/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();
}
另外,请确保您有正确的参考QueryableExtensions.SingleOrDefaultAsync Method (IQueryable)
答案 2 :(得分:1)
添加 使用System.Data.Entity 到CustomerRepository.cs
顶部的using语句更改FindAsync的返回类型以返回IQueryable
请参阅QueryableExtensions vor进一步指导
此外,请不要将阻止调用(.Result)与async / await混合使用,如后面的评论所示。