创建通用存储库的异步版本

本文关键字:异步 版本 存储 创建 | 更新日期: 2023-09-27 18:17:09

我有一个实现以下接口的通用存储库:

public interface IRepository
{
  IUnitOfWork UnitOfWork { get; }

  IEnumerable<TEntity> GetWithRawSql<TEntity>(string query, params object[] parameters) where TEntity : class;
  TEntity GetByKey<TEntity>(object keyValue) where TEntity : class;
  IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class;
  IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
  IQueryable<TEntity> GetQuery<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  TEntity Single<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class;
  TEntity Single<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
  TEntity First<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  void Add<TEntity>(TEntity entity) where TEntity : class;
  void Attach<TEntity>(TEntity entity) where TEntity : class;
  void Delete<TEntity>(TEntity entity) where TEntity : class;
  void Delete<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class;
  void Delete<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  void Update<TEntity>(TEntity entity) where TEntity : class;
  IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class;
  TEntity FindOne<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
  TEntity FindOne<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class;
  IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class;
  IEnumerable<TEntity> Get<TEntity, TOrderBy>(Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
    int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class;
  IEnumerable<TEntity> Get<TEntity, TOrderBy>(Expression<Func<TEntity, bool>> criteria,
    Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex, int pageSize,
    SortOrder sortOrder = SortOrder.Ascending) where TEntity : class;
  IEnumerable<TEntity> Get<TEntity, TOrderBy>(ISpecification<TEntity> specification,
    Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex, int pageSize,
    SortOrder sortOrder = SortOrder.Ascending) where TEntity : class;
  int Count<TEntity>() where TEntity : class;
  int Count<TEntity>(Expression<Func<TEntity, bool>> criteria) where TEntity : class;
  int Count<TEntity>(ISpecification<TEntity> criteria) where TEntity : class;
}

这个接口属于一个通用存储库的修改版本,由huyrua的博客实现。我需要有一些方法的异步版本。例如,我有以下GetWithRawSql方法的实现:

public IEnumerable<TEntity> GetWithRawSql<TEntity>(string query, params object[] parameters) where TEntity : class
{
    return DbContext.Set<TEntity>().SqlQuery(query, parameters).ToList();
}

和Async版本我已经实现了以下内容:

public async Task<IEnumerable<TEntity>> GetWithRawSqlAsync<TEntity>(string query, params object[] parameters) where TEntity : class
{
    return await Task.Run(() => GetWithRawSql<TEntity>(query, parameters));
}

或相同的GetByKey方法:

public async Task<TEntity> GetByKeyAsync<TEntity>(object keyValue) where TEntity : class
{
    return await Task.Run(() => GetByKey<TEntity>(keyValue));
}

上面的实现看起来像一个快速和肮脏的工作。您将如何实现上述方法?使用

可能会遇到哪些问题?
await Task.Run(() => GetWithRawSql<TEntity>(query, parameters));

在我的存储库中吗?对于完整的植入,你可以看看博客,我使用实体框架6.1.1。

创建通用存储库的异步版本

你所做的是async over sync,当处理异步工作时,这是一个反模式。

EF6已经开箱即用了一个async api,它不会在后台使用任何新的线程,而是使用数据库公开的异步IO工作来消耗其工作。

当你去异步而不是同步,你通常结束了一堆线程,基本上坐在那里等待查询返回,这不能很好地扩展,并使用冗余线程,这是不需要的,当处理IO绑定操作。此外,当人们看到async方法时,他们从不说"他可能使用了一个新线程来运行同步版本",他们通常会说"这个async实现将为IO绑定工作节省不必要的线程使用"

这是一个简单的UpdateAsync方法完成EF6:

public static async Task<string> UpdateAsync(Customer obj)
{
    NorthwindEntities db = new NorthwindEntities();
    // This is an async method
    Customer existing = await db.Customers.FindAsync(obj.CustomerID);         
    existing.CompanyName = obj.CompanyName;
    existing.ContactName = obj.ContactName;
    existing.Country = obj.Country;
    await db.SaveChangesAsync(); // This is an async method
    return "Customer updated successfully!";
}

你可以阅读更多关于EF6和async方法:

  1. 使用实体框架执行异步操作
  2. 异步查询&保存(EF6起)