上一讲中,我们定义了三个异步操作接口,这回我们将对它进行实现,而有一个基础知识需要大家清楚,那就是实现接口的方式,一般我们使用默认的方式(隐式实现),这种方法实现的接口方式均为public,即它可以脱离接口,而直接通过类对象去访问,而当一个类继承多个接口,而这些接口中都有相同的方法时,我们就需要显示实现接口了,显示实现的接口成员只能通过接口实例去访问它,今天我们对DbContextRepository的改造就用到了这个特性。
基本关键字
async:用来标识这个方法为异步方法
await:用在异步方法中,它可以等待异步方法的返回值,即用来阻塞主线程,迫使它等待异步请求,当请求成功返回后,再执行下面的代码
Task:异步返回的结果,它有泛型版本,Task表示返回为void,而使用泛型版本时Task<T>返回结果为类型T
EF6引入的异步提交机制
public virtual Task<int> SaveChangesAsync();
一般地,仓储大叔习惯将系统方法变为自已的方法,这样方便以后去维护,如向SaveChangesAsync方法添加个什么日志,事件之类的东西,所以,就有了自己的版本。
/// <summary> /// 异步提交到数据库 /// </summary> protected async Task SaveChangesAsync() { try { await Db.SaveChangesAsync(); } catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//捕获实体验证异常 { var sb = new StringBuilder(); dbEx.EntityValidationErrors.First().ValidationErrors.ToList().ForEach(i => { sb.AppendFormat("属性为:{0},信息为:{1}\n\r", i.PropertyName, i.ErrorMessage); }); if (Logger == null) throw new Exception(sb.ToString()); Logger(sb.ToString() + "处理时间:" + DateTime.Now); } catch (OptimisticConcurrencyException)//并发冲突异常 { } catch (Exception ex)//捕获所有异常 { if (Logger == null)//如果没有定义日志功能,就把异常抛出来吧 throw new Exception(ex.Message); Logger(ex.Message + "处理时间:" + DateTime.Now); }
对DbContextRepository进行改造
下面代码,选自仓储大叔的DbContextRepository.cs文件,它是显式实现的异步操作接口的,具体实现如下
#region 异步操作-显示实现的接口,只能为接口实例进行调用 #region IExtensionRepositoryAsync<TEntity> 成员 async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.Insert(IEnumerable<TEntity> item) { item.ToList().ForEach(i => { Db.Entry<TEntity>(i); Db.Set<TEntity>().Add(i); }); await this.SaveChangesAsync(); } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.Update(IEnumerable<TEntity> item) { item.ToList().ForEach(i => { Db.Set<TEntity>().Attach(i); Db.Entry(i).State = EntityState.Modified; }); try { await this.SaveChangesAsync(); } catch (OptimisticConcurrencyException)//并发冲突异常 { } } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.Delete(IEnumerable<TEntity> item) { item.ToList().ForEach(i => { Db.Set<TEntity>().Attach(i); Db.Set<TEntity>().Remove(i); }); await this.SaveChangesAsync(); } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.BulkInsert(IEnumerable<TEntity> item, bool isRemoveIdentity) { await Task.Run(() => { this.BulkInsert(item, isRemoveIdentity); }); } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.BulkInsert(IEnumerable<TEntity> item) { await Task.Run(() => { this.BulkInsert(item); }); } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.BulkUpdate(IEnumerable<TEntity> item, params string[] fieldParams) { await Task.Run(() => { this.BulkUpdate(item); }); } async System.Threading.Tasks.Task IExtensionRepositoryAsync<TEntity>.BulkDelete(IEnumerable<TEntity> item) { await Task.Run(() => { this.BulkDelete(item); }); } #endregion #region IRepositoryAsync<TEntity> 成员 async System.Threading.Tasks.Task IRepositoryAsync<TEntity>.Insert(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Insert)); Db.Entry<TEntity>(item); Db.Set<TEntity>().Add(item); await this.SaveChangesAsync(); OnAfterSaved(new SavedEventArgs(item, SaveAction.Insert)); } async System.Threading.Tasks.Task IRepositoryAsync<TEntity>.Delete(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Delete)); Db.Set<TEntity>().Attach(item); Db.Set<TEntity>().Remove(item); await this.SaveChangesAsync(); OnAfterSaved(new SavedEventArgs(item, SaveAction.Delete)); } async System.Threading.Tasks.Task IRepositoryAsync<TEntity>.Update(TEntity item) { OnBeforeSaved(new SavedEventArgs(item, SaveAction.Update)); Db.Set<TEntity>().Attach(item); Db.Entry(item).State = EntityState.Modified; try { await this.SaveChangesAsync(); } catch (OptimisticConcurrencyException)//并发冲突异常 { } OnAfterSaved(new SavedEventArgs(item, SaveAction.Update)); } #endregion #endregion
好了,到目前为止我们对DbContextRepository的改造就结束了,下一讲我们将介绍如何在具体项目中使用EF的异步功能,敬请期待!
时间: 2024-10-27 13:28:18