EF架构~EF异步改造之路~仓储接口的改造
C#5.0带来了并行编程
{C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语言→C#5.0异步编程}
随着C#5.0在.net4.5出来之后,它们主推的并行技术也逐渐变得越来越热,这种热量已经传到了我这里,身为仓储大叔的我,一定也对自己的仓储进行并行化的改造,这是大势所趋,呵呵,今天主要是把我的IRepository.Core项目进行扩展,即添加一些对应的并行接口,然后让我的并行(异步)仓储去实现它,事实上,.net的ef这块,实现异步(并行)非常容易,在C#5.0里由于async/await关键字的出现,这使得实现异步变得更加容易了,呵呵,还是那句话,身为.net领域的程序编写者,我感到万心幸福!
IRepository变成了IRepositoryAsync
/// <summary> /// 异步操作 /// 基础的数据操作规范 /// 与ORM架构无关 /// </summary> /// <typeparam name="TEntity"></typeparam> public interface IRepositoryAsync<TEntity> where TEntity : class { /// <summary> /// 设定数据上下文,它一般由构架方法注入 /// </summary> /// <param name="unitOfWork"></param> void SetDbContext(IUnitOfWork unitOfWork); /// <summary> /// 添加实体并提交到数据服务器 /// </summary> /// <param name="item">Item to add to repository</param> Task Insert(TEntity item); /// <summary> /// 移除实体并提交到数据服务器 /// 如果表存在约束,需要先删除子表信息 /// </summary> /// <param name="item">Item to delete</param> Task Delete(TEntity item); /// <summary> /// 修改实体并提交到数据服务器 /// </summary> /// <param name="item"></param> Task Update(TEntity item); /// <summary> /// 得到指定的实体集合(延时结果集) /// Get all elements of type {T} in repository /// </summary> /// <returns>List of selected elements</returns> IQueryable<TEntity> GetModel(); /// <summary> /// 根据主键得到实体 /// </summary> /// <param name="id"></param> /// <returns></returns> TEntity Find(params object[] id); }
IExtensionRepository变成了IExtensionRepositoryAsync
/// <summary> /// 异步操作 /// 扩展的Repository操作规范 /// </summary> public interface IExtensionRepositoryAsync<TEntity> : IRepositoryAsync<TEntity>, IOrderableRepository<TEntity> where TEntity : class { /// <summary> /// 添加集合[集合数目不大时用此方法,超大集合使用BulkInsert] /// </summary> /// <param name="item"></param> Task Insert(IEnumerable<TEntity> item); /// <summary> /// 修改集合[集合数目不大时用此方法,超大集合使用BulkUpdate] /// </summary> /// <param name="item"></param> Task Update(IEnumerable<TEntity> item); /// <summary> /// 删除集合[集合数目不大时用此方法,超大集合使用批量删除] /// </summary> /// <param name="item"></param> Task Delete(IEnumerable<TEntity> item); /// <summary> /// 根据指定lambda表达式,得到延时结果集 /// </summary> /// <param name="predicate"></param> /// <returns></returns> IQueryable<TEntity> GetModel(Expression<Func<TEntity, bool>> predicate); /// <summary> /// 根据指定lambda表达式,得到第一个实体 /// </summary> /// <param name="predicate"></param> /// <returns></returns> TEntity Find(Expression<Func<TEntity, bool>> predicate); /// <summary> /// 批量添加,添加之前可以去除自增属性,默认不去除 /// </summary> /// <param name="item"></param> /// <param name="isRemoveIdentity"></param> Task BulkInsert(IEnumerable<TEntity> item, bool isRemoveIdentity); /// <summary> /// 批量添加 /// </summary> /// <param name="item"></param> Task BulkInsert(IEnumerable<TEntity> item); /// <summary> /// 批量更新 /// </summary> /// <param name="item"></param> Task BulkUpdate(IEnumerable<TEntity> item, params string[] fieldParams); /// <summary> /// 批量删除 /// </summary> /// <param name="item"></param> Task BulkDelete(IEnumerable<TEntity> item); /// <summary> /// 保存之后 /// </summary> event Action<SavedEventArgs> AfterSaved; /// <summary> /// 保存之前 /// </summary> event Action<SavedEventArgs> BeforeSaved; }
ISpecificationRepository变成了ISpecificationRepositoryAsync
/// <summary> /// EF底层构架,关于规约功能的仓储接口 /// </summary> /// <typeparam name="TEntity"></typeparam> public interface ISpecificationRepositoryAsync<TEntity> : IExtensionRepositoryAsync<TEntity> where TEntity : class { /// <summary> /// 根据指定规约,得到延时结果集 /// </summary> /// <param name="specification"></param> /// <returns></returns> IQueryable<TEntity> GetModel(ISpecification<TEntity> specification); /// <summary> /// 根据指定规约,得到第一个实体 /// </summary> /// <param name="specification"></param> /// <returns></returns> TEntity Find(ISpecification<TEntity> specification); /// <summary> /// 带排序功能的,根据指定规约,得到结果集 /// </summary> /// <param name="orderBy"></param> /// <param name="specification"></param> /// <returns></returns> IQueryable<TEntity> GetModel(Action<IOrderable<TEntity>> orderBy, ISpecification<TEntity> specification); }
大家可以看到,仓储大叔的异步操作接口都是以Async结尾的,这也是遵从了微软的规范的,例如同步的ToList()方法在改成异步后变成了ToListAsync(),而占占并没有在原有接口上进行修改,而是扩展了异步接口,方法名称并没有变,感觉这样对程序开发者
来说更友好,更能接受,即我们的CUD操作还是(Insert,Update,Delete),只是在接口上进行区分,你用IRepository接口来声明实例,生成的就是同步操作,而使用IRepositoryAsync声明的实例,就是以异步的方式实现操作。