实体框架 - 异步查询
异步编程涉及在后台执行操作,以便主线程可以继续其自己的操作。这样,主线程可以在后台线程处理手头的任务时保持用户界面响应。
Entity Framework 6.0 支持异步操作来查询和保存数据。
异步操作可以通过以下方式帮助您的应用程序 −
- 使您的应用程序对用户交互的响应更快
- 提高应用程序的整体性能
您可以通过多种方式执行异步操作。但是 .NET Framework 4.5 中引入了 async/await 关键字,这让您的工作变得简单。
您唯一需要遵循的是 async/await 模式,如以下代码片段所示。
让我们看一下以下示例(不使用 async/await),其中 DatabaseOperations 方法将新学生保存到数据库,然后从数据库中检索所有学生,最后在控制台上打印一些附加消息。
class Program { static void Main(string[] args) { Console.WriteLine("Database Operations Started"); DatabaseOperations(); Console.WriteLine(); Console.WriteLine("Database Operations Completed"); Console.WriteLine(); Console.WriteLine("Entity Framework Tutorials"); Console.ReadKey(); } public static void DatabaseOperations() { using (var context = new UniContextEntities()) { // Create a new student and save it context.Students.Add(new Student { FirstMidName = "Akram", LastName = "Khan", EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())}); Console.WriteLine("Calling SaveChanges."); context.SaveChanges(); Console.WriteLine("SaveChanges completed."); // Query for all Students ordered by first name var students = (from s in context.Students orderby s.FirstMidName select s).ToList(); // Write all students out to Console Console.WriteLine(); Console.WriteLine("All Student:"); foreach (var student in students) { string name = student.FirstMidName + " " + student.LastName; Console.WriteLine(" " + name); } } } }
执行上述代码后,您将收到以下输出 −
Calling SaveChanges. SaveChanges completed. All Student: Akram Khan Ali Khan Ali Alexander Arturo Anand Bill Gates Gytis Barzdukas Laura Nornan Meredith fllonso Nino Olioetto Peggy Justice Yan Li Entity Framework Tutorials
让我们使用新的 async 和 await 关键字并对 Program.cs 进行以下更改
添加 System.Data.Entity 命名空间,它将提供 EF 异步扩展方法。
添加 System.Threading.Tasks 命名空间,它将允许我们使用 Task 类型。
更新 DatabaseOperations 以标记为 async 并返回 Task。
调用 SaveChanges 的异步版本并等待其完成。
调用 ToList 的异步版本并等待结果。
class Program { static void Main(string[] args) { var task = DatabaseOperations(); Console.WriteLine(); Console.WriteLine("Entity Framework Tutorials"); task.Wait(); Console.ReadKey(); } public static async Task DatabaseOperations() { using (var context = new UniContextEntities()) { // Create a new blog and save it context.Students.Add(new Student { FirstMidName = "Salman", LastName = "Khan", EnrollmentDate = DateTime.Parse(DateTime.Today.ToString())}); Console.WriteLine("Calling SaveChanges."); await context.SaveChangesAsync(); Console.WriteLine("SaveChanges completed."); // Query for all Students ordered by first name var students = await (from s in context.Students orderby s.FirstMidName select s).ToListAsync(); // Write all students out to Console Console.WriteLine(); Console.WriteLine("All Student:"); foreach (var student in students) { string name = student.FirstMidName + " " + student.LastName; Console.WriteLine(" " + name); } } } }
执行后,它将产生以下输出。
Calling SaveChanges. Entity Framework Tutorials SaveChanges completed. All Student: Akram Khan Ali Khan Ali Alexander Arturo Anand Bill Gates Gytis Barzdukas Laura Nornan Meredith fllonso Nino Olioetto Peggy Justice Salman Khan Yan Li
现在代码是异步的,您可以观察到程序的不同执行流程。
SaveChanges 开始将新的 Student 推送到数据库,然后 DatabaseOperations 方法返回(即使它尚未完成执行),Main 方法中的程序流继续。
然后将消息写入控制台。
托管线程在 Wait 调用上被阻止,直到数据库操作完成。一旦完成,将执行 DatabaseOperations 的其余部分。
SaveChanges 完成。
从数据库中检索所有学生并写入控制台。
我们建议您逐步执行上述示例,以便更好地理解。