回到目录

返回异步与并行目录

上一讲中,我们定义了三个异步操作接口,这回我们将对它进行实现,而有一个基础知识需要大家清楚,那就是实现接口的方式,一般我们使用默认的方式(隐式实现),这种方法实现的接口方式均为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的异步功能,敬请期待!

回到目录

返回异步与并行目录

EF架构~EF异步改造之路~让DbContextRepository去实现异步接口的更多相关文章

  1. 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出来之后,它们 ...

  2. EF架构~EF异步改造之路~仓储接口的改造~续

    回到目录 返回异步与并行目录 在写完仓储接口的改造改造后,总觉得有个代码的坏味道,这种味道源于它的DRP,即重复的代码太多了,即异步操作和同步操作其实只是在insert,update和delete上有 ...

  3. EF架构~为EF DbContext生成的实体添加注释(T5模板应用)

    回到目录 相关文章系列 第八回 EF架构~将数据库注释添加导入到模型实体类中 第二十一回  EF架构~为EF DbContext生成的实体添加注释(T4模板应用) 第二十二回EF架构~为EF DbCo ...

  4. EF架构~数据分批批量提交

    回到目录 对于大数据量提交,包括插入,更新和删除,我始终不建议用EF自带的方法,因为它会增加与数据库的交互次数,一般地,EF的一个上下文在提交时会打开一个数据连接,然后把转换成的SQL语句一条一条的发 ...

  5. EF架构~基于EF数据层的实现

    回到目录 之前写过关于实现一个完整的EF架构的文章,文章的阅读量也是满大的,自己很欣慰,但是,那篇文章是我2011年写的,所以,技术有些不成熟,所以今天把我的2014年写的EF底层架构公开一下,这个架 ...

  6. EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一

    回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是sect ...

  7. EF架构~扩展一个分页处理大数据的方法

    回到目录 最近总遇到大数据的问题,一次性处理几千万数据不实际,所以,我们需要对大数据进行分块处理,或者叫分页处理,我在EF架构里曾经写过类似的,那是在进行BulkInsert时,对大数据批量插入时候用 ...

  8. EF架构~CodeFirst数据迁移与防数据库删除

    回到目录 本文介绍两个概念,防数据库自动删除,这是由于在code first模式下,当数据实体发生变化时,会对原来数据库进行删除,并将新数据表添加进来,但这对于我们的运营环境数据库,是万万不能接受的, ...

  9. EF架构~CodeFirst生产环境的Migrations

    回到目录 Migrations即迁移,它是EF的code first模式出现的产物,它意思是说,将代码的变化反映到数据库上,这种反映有两种环境,一是本地开发环境,别一种是服务器的生产环境,本地开发环境 ...

随机推荐

  1. 一个App完成入门篇(六)- 完成通讯录页面

    第五章和第六章间隔时间有点长,对不起大家了.下面继续. 本节教程将要教会大家如何加载本地通讯录. 导入项目 导入通讯录 自定义js模块 发送和订阅page消息 将要学习的demo效果图如下所示 1. ...

  2. [史上最全]C#(VB.NET)中位运算符工作过程剖析(译)

    原文地址CodeProject 目录 介绍 “二进制-十进制”相互转换 十进制->二进制 二进制->十进制 OR运算符(按位或|) OR运算符工作方式 FlagsAttribute AND ...

  3. [Unity3D]自己动手重制坦克舰队ArmadaTank

    [Unity3D]自己动手重制坦克舰队ArmadaTank 我玩过一款坦克游戏ArmadaTank(坦克舰队),如下图所示 几个月前我尝试用Unity3D重制这款游戏,已经可以玩起来了.下面是在PC上 ...

  4. Golang与C#之switch区别

    Golang与C#之switch区别 Go是Google开发的一种编译型,可并行化,并具有垃圾回收功能的编程语言. C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序 ...

  5. Atitit  补充说明 sql知识图谱与线路图attilax总结补充说明

    Atitit  补充说明 sql知识图谱与线路图attilax总结补充说明 1. 常见编程语言的分类  :命令式语言.函数式语言.逻辑语言1 1.1. 按照编程语言的代际划分,又2gl,3gl,4gl ...

  6. JS原生第七篇 (帅哥)

    1.1 复习 offset   自己的 偏移 offsetWidth    得到自己的宽度 offsetHeight 构成 :   width  +   padding  +  border div ...

  7. 异步方法不能使用ref和out的解决方法

    异常处理汇总-后端系列:http://www.cnblogs.com/dunitian/p/4523006.html 应用场景==>后端现在都是用异步方法,那么分页是必不可少的,于是就有了这个问 ...

  8. 自定义配置UEditor 工具栏上的按钮列表

    修改配置项的方法: 1. 方法一:修改 ueditor.config.js 里面的 toolbars 2. 方法二:实例化编辑器的时候传入 toolbars 参数 方法一:在ueditor.confi ...

  9. 深入理解DOM事件机制系列第二篇——事件处理程序

    × 目录 [1]HTML [2]DOM0级 [3]DOM2级[4]IE[5]总结 前面的话 事件处理程序又叫事件侦听器,实际上就是事件的绑定函数.事件发生时会执行函数中相应代码.事件处理程序有HTML ...

  10. 一起学微软Power BI系列-官方文档-入门指南(4)Power BI的可视化

    在前面的系列文章中,我们介绍了官方有关获取数据,以及建模的原始文档和基本介绍.今天继续给大家介绍官方文档中,有关可视化的内容.实际上获获取数据和建模更注重业务关系的处理,而可视化则关注对数据的解读.这 ...