zoukankan      html  css  js  c++  java
  • Entity Framework异步查询和保存

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

    本文将覆盖一下主题:

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

    实例演练异步操作

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

    创建模型

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

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

    添加EntityFramework NuGet包到项目中。

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

     1 using System.Collections.Generic; 
     2 using System.Data.Entity; 
     3  
     4 namespace AsyncDemo 
     5 { 
     6     public class BloggingContext : DbContext 
     7     { 
     8         public DbSet<Blog> Blogs { get; set; } 
     9         public DbSet<Post> Posts { get; set; } 
    10     } 
    11  
    12     public class Blog 
    13     { 
    14         public int BlogId { get; set; } 
    15         public string Name { get; set; } 
    16  
    17         public virtual List<Post> Posts { get; set; } 
    18     } 
    19  
    20     public class Post 
    21     { 
    22         public int PostId { get; set; } 
    23         public string Title { get; set; } 
    24         public string Content { get; set; } 
    25  
    26         public int BlogId { get; set; } 
    27         public virtual Blog Blog { get; set; } 
    28     } 
    29 }

    创建同步程序

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

     1 using System; 
     2 using System.Linq; 
     3  
     4 namespace AsyncDemo 
     5 { 
     6     class Program 
     7     { 
     8         static void Main(string[] args) 
     9         { 
    10             PerformDatabaseOperations(); 
    11  
    12             Console.WriteLine(); 
    13             Console.WriteLine("Quote of the day"); 
    14             Console.WriteLine(" Don't worry about the world coming to an end today... "); 
    15             Console.WriteLine(" It's already tomorrow in Australia."); 
    16  
    17             Console.WriteLine(); 
    18             Console.WriteLine("Press any key to exit..."); 
    19             Console.ReadKey(); 
    20         } 
    21  
    22         public static void PerformDatabaseOperations() 
    23         { 
    24             using (var db = new BloggingContext()) 
    25             { 
    26                 // Create a new blog and save it 
    27                 db.Blogs.Add(new Blog 
    28                 { 
    29                     Name = "Test Blog #" + (db.Blogs.Count() + 1) 
    30                 }); 
    31                 db.SaveChanges(); 
    32  
    33                 // Query for all blogs ordered by name 
    34                 var blogs = (from b in db.Blogs 
    35                             orderby b.Name 
    36                             select b).ToList(); 
    37  
    38                 // Write all blogs out to Console 
    39                 Console.WriteLine(); 
    40                 Console.WriteLine("All blogs:"); 
    41                 foreach (var blog in blogs) 
    42                 { 
    43                     Console.WriteLine(" " + blog.Name); 
    44                 } 
    45             } 
    46         } 
    47     } 
    48 }

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

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

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

    改造为异步操作

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

     1 using System; 
     2 using System.Data.Entity; 
     3 using System.Linq; 
     4 using System.Threading.Tasks; 
     5  
     6 namespace AsyncDemo 
     7 { 
     8     class Program 
     9     { 
    10         static void Main(string[] args) 
    11         { 
    12             var task = PerformDatabaseOperations(); 
    13  
    14             Console.WriteLine("Quote of the day"); 
    15             Console.WriteLine(" Don't worry about the world coming to an end today... "); 
    16             Console.WriteLine(" It's already tomorrow in Australia."); 
    17  
    18             task.Wait(); 
    19  
    20             Console.WriteLine(); 
    21             Console.WriteLine("Press any key to exit..."); 
    22             Console.ReadKey(); 
    23         } 
    24  
    25         public static async Task PerformDatabaseOperations() 
    26         { 
    27             using (var db = new BloggingContext()) 
    28             { 
    29                 // Create a new blog and save it 
    30                 db.Blogs.Add(new Blog 
    31                 { 
    32                     Name = "Test Blog #" + (db.Blogs.Count() + 1) 
    33                 }); 
    34                 Console.WriteLine("Calling SaveChanges."); 
    35                 await db.SaveChangesAsync(); 
    36                 Console.WriteLine("SaveChanges completed."); 
    37  
    38                 // Query for all blogs ordered by name 
    39                 Console.WriteLine("Executing query."); 
    40                 var blogs = await (from b in db.Blogs 
    41                             orderby b.Name 
    42                             select b).ToListAsync(); 
    43  
    44                 // Write all blogs out to Console 
    45                 Console.WriteLine("Query completed with following results:"); 
    46                 foreach (var blog in blogs) 
    47                 { 
    48                     Console.WriteLine(" - " + blog.Name); 
    49                 } 
    50             } 
    51         } 
    52     } 
    53 }

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

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

  • 相关阅读:
    数组
    mysql优化思路
    mysql_存储过程
    mysql_函数
    mysql_结构
    mysql_触发器
    mysql_变量
    mysql_事务
    mysql总结
    mysql备份
  • 原文地址:https://www.cnblogs.com/from1991/p/5425263.html
Copyright © 2011-2022 走看看