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

时间:2014-08-08 09:34:19

标签: c# .net entity-framework generics async-await

我有一个实现以下界面的Generic存储库:

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's blog实现的通用存储库的修改版本。 我需要有一些方法的异步版本。例如,我有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));

在我的存储库中?对于完全植入,您可以查看博客,并使用Entity framework 6.1.1获取您的信息。

1 个答案:

答案 0 :(得分:6)

你正在做的是async over sync,在处理异步工作时它是一种反模式。

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

当你进行异步同步时,你通常最终会调出一堆线程,这些线程基本上就坐在那里等待查询返回并且根本不能很好地扩展,并使用冗余的线程处理IO绑定操作时需要。更重要的是,当人们看到async方法时,他们从不说“他可能正在使用新线程来运行同步版本”,他们通常会说“this {{1}实现将为我节省不必要的线程使用IO绑定工作“

这是使用EF6完成的简单async方法:

UpdateAsync

您可以阅读有关EF6和异步方法的更多信息:

  1. Performing Asynchronous Operations Using Entity Framework
  2. Async Query & Save (EF6 onwards)