EF6开始提供了通过async和await关键字实现异步查询和保存的支持(.net 4.5及更高版本)。虽然不是所有的操作都能从异步中获益,但是耗时的操作、网络或IO密集型任务中,使用异步可以提升客户端性能和增强服务器的扩展性。

本文将覆盖一下主题:

  • 实例演练异步操作
  • 创建模型
  • 创建同步程序
  • 改为异步操作

实例演练异步操作

下面演练将通过对比,很容易的观察异步操作和同步操作,该演练目的不是说明何时才是异步操作的关键场景。

创建模型

下面使用CodeFirst的流程创建模型并生成数据库,不过异步方法可以很好的工作于所有EF模型,包括EF设计器生成的模型。

创建一个控制台应用程序AsyncDemo。

添加EntityFramework NuGet包到项目中。

添加Model.cs到项目中,代码如下:

 using System.Collections.Generic;
using System.Data.Entity; namespace AsyncDemo
{
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
} public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; } public virtual List<Post> Posts { get; set; }
} public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; } public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
}

创建同步程序

有了EF模型,下面通过代码模拟数据库存取。

 using System;
using System.Linq; namespace AsyncDemo
{
class Program
{
static void Main(string[] args)
{
PerformDatabaseOperations(); Console.WriteLine();
Console.WriteLine("Quote of the day");
Console.WriteLine(" Don't worry about the world coming to an end today... ");
Console.WriteLine(" It's already tomorrow in Australia."); Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
} public static void PerformDatabaseOperations()
{
using (var db = new BloggingContext())
{
// Create a new blog and save it
db.Blogs.Add(new Blog
{
Name = "Test Blog #" + (db.Blogs.Count() + )
});
db.SaveChanges(); // Query for all blogs ordered by name
var blogs = (from b in db.Blogs
orderby b.Name
select b).ToList(); // Write all blogs out to Console
Console.WriteLine();
Console.WriteLine("All blogs:");
foreach (var blog in blogs)
{
Console.WriteLine(" " + blog.Name);
}
}
}
}
}

上面代码通过调用PerformDatabaseOperations() 保存一个Blog对象到数据库中,然后从数据库中检索所有Blog,并显示到控制台,然后显示一行文本”Quote of the day“。

由于上面程序是同步执行的,所有可以观察到程序按下面流程执行:

  1. SaveChanges保存Blog对象到数据库中。
  2. SaveChanges完成。
  3. 发送查询Blog请求到数据库。
  4. 查询返回结果,并写入控制台。
  5. 显示文本“Quote of the day”到控制台。

改造为异步操作

对上面程序加以修改,使用async和await关键字实现异步操作。

 using System;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks; namespace AsyncDemo
{
class Program
{
static void Main(string[] args)
{
var task = PerformDatabaseOperations(); Console.WriteLine("Quote of the day");
Console.WriteLine(" Don't worry about the world coming to an end today... ");
Console.WriteLine(" It's already tomorrow in Australia."); task.Wait(); Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
} public static async Task PerformDatabaseOperations()
{
using (var db = new BloggingContext())
{
// Create a new blog and save it
db.Blogs.Add(new Blog
{
Name = "Test Blog #" + (db.Blogs.Count() + )
});
Console.WriteLine("Calling SaveChanges.");
await db.SaveChangesAsync();
Console.WriteLine("SaveChanges completed."); // Query for all blogs ordered by name
Console.WriteLine("Executing query.");
var blogs = await (from b in db.Blogs
orderby b.Name
select b).ToListAsync(); // Write all blogs out to Console
Console.WriteLine("Query completed with following results:");
foreach (var blog in blogs)
{
Console.WriteLine(" - " + blog.Name);
}
}
}
}
}

现在程序变为异步执行,可以观察到异步执行顺序为:

  1. 发送SaveChanges请求到数据库。
  2. 该请求发送给数据库时,当前线程不在占用CPU时间,从方法PerformDatabaseOperations中返回(虽然该方法还没有执行完成),控制权返回给主线程执行。
  3. 显示字符串“Quote of the day ”到控制台。
  4. SaveChanges完成。
  5. 发起查询Blogs请求到数据库。
  6. 查询完成返回结果,并显示到控制台。

Entity Framework异步查询和保存的更多相关文章

  1. 整理一下Entity Framework的查询

    整理一下Entity Framework的查询 2012-08-30 13:41:59 标签:Entity Framework 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信 ...

  2. Entity Framework 简单查询

    前言 首先来简单的复习一下如何使用Code First. 第一步还是先建立一个控制台的应用程序,然后通过Nuget添加Entity Framework.那么同时会给packages.config和Ap ...

  3. 整理一下Entity Framework的查询 [转]

    Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...

  4. 转:整理一下Entity Framework的查询

    Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...

  5. Entity Framework的查询

    Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...

  6. Entity Framework关联查询以及数据加载(延迟加载,预加载)

    数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...

  7. Entity Framework (二) 查询

    待完善-------------------------------------- ----------- base 关键字用于从派生类中访问基类的成员: 调用基类上已被其他方法重写的方法. 指定创建 ...

  8. Entity Framework: 视图查询时重复返回第一行值, duplicate frst rows in resultset from a view

    http://blog.csdn.net/riverlau/article/details/7476449 1. 使用rownumber给view加上一个标示列 SELECT ROW_NUMBER() ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7  标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...

随机推荐

  1. fatal error C1010: 在查找预编译头时遇到意外的文件结尾 (转)

    错误描述:fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“#include "stdafx.h"”? 错误分析:     此错误发生 ...

  2. if __name__ == '__main__'的作用和原理

    最简单的理解就是这样: __name__ 是当前模块名,当模块被直接运行时,模块名为 __main__. 所以 if __name__ == '__main__' 这句话的意思就是当前模块被直接运行时 ...

  3. FP回写报错

    报错信息如下: 提示java for mo 2022报错 执行的DTS如下: 解决方法:(原因:SAP归档日志满了,导致连接失败)1.检查表temp_out_pr中的siteid是否有三个工厂的数据确 ...

  4. 压力测试工具--Siege

    Siege是一款开源的压力测试工具,设计用于评估WEB应用在压力下的承受能力.可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行.s ...

  5. VUE+WebPack前端游戏设计:实现物体的拖拽动态特效

  6. lucene4

    在lucene通过对应的API建立索引.在学习的过程中我们了解到lucene下面索引的建立与关系数据库有相似的地方. IndexReader.delete删除有两种删除的形式. 第三个改变Docume ...

  7. 关于《Spark快速大数据分析》运行例子遇到的报错及解决

    一.描述 在书中第二章,有一个例子,构建完之后,运行: ${SPARK_HOME}/bin/spark-submit --class com.oreilly.learningsparkexamples ...

  8. 制作initramfs/initrd镜像

    Linux kernel在自身初始化完成之后,需要能够找到并运行第一个用户程序(这个程序通常叫做"init"程序).用户程序存在于文件系统之中,因此,内核必须找到并挂载一个文件系统 ...

  9. VisualVM远程连接Tomcat(转)

    转自:http://www.cnblogs.com/sunshine-2015/p/5547128.html VisualVM VisualVm是一个将很多JDK命令工具可视化的windows程序,直 ...

  10. LoadRunner11学习记录四 -- 集合点

    LoadRunner集合点的设置: 我们来想象一个场景,10名运动员参加长跑比赛,出发点同时起跑,他们是并排奔跑的:跑了N圈之后,因为有体能更强的,有体能稍弱的,他们的队形并排变成了前后.几乎一个跑道 ...