Asynchronous execution has been introduced in .NET 4.5 which can be useful in Entity Framework.
EF 6 allows us to execute a query and command asynchronously using an instance of DbContext
.
Let's see how to execute asynchronous queries first and then, we will see an asynchronous call to context.SaveChanges.
The following is an example of the async method which executes a LINQ-to-Entity query asynchronously and returns the result.
private static async Task<Student> GetStudent() { Student student = null; using (var context = new SchoolDBEntities()) { Console.WriteLine("Start GetStudent..."); student = await (context.Students.Where(s => s.StudentID == 1).FirstOrDefaultAsync<Student>()); Console.WriteLine("Finished GetStudent..."); } return student; }
As you can see in the above code, the GetStudent()
method is marked with the async
keyword, which makes it an asynchronous method.
The return type of the asynchrounous method must be Task<T>
. The GetStudent()
method returns an object of the Student
entity, so return type must be of Task<Student>
type.
Also, the LINQ query is marked with the await
keyword.
This frees up the calling thread to execute other code until it executes the query and returns the result.
We have used the FirstOrDefaultAsync
async extension method to get the result. You may use other async methods appropriately such as SingleOrDefaultAsync
, ToListAsyn
etc.
EF API provides the SaveChangesAsync()
method to save entities to the database asynchronously. The following SaveStudent
method saves the Student
entity to the database asynchronously.
private static async Task SaveStudent(Student editedStudent) { using (var context = new SchoolDBEntities()) { context.Entry(editedStudent).State = EntityState.Modified; Console.WriteLine("Start SaveStudent..."); int x = await (context.SaveChangesAsync()); Console.WriteLine("Finished SaveStudent..."); } }
The following example demonstrates executing an async query, getting the result and saving the modified entity.
public static void AsyncQueryAndSave() { var query = GetStudent(); Console.WriteLine("Do something else here till we get the query result.."); query.Wait(); var student = query.Result; student.FirstName = "Steve"; var numOfSavedStudent = SaveStudent(student); Console.WriteLine("Do something else here till we save a student.." ); studentSave.Wait(); Console.WriteLine("Saved Entities: {0}", numOfSavedStudent.Result); }
In the above example, the async method GetStudent()
is called and it stores the reference in the query
variable.
This will start to execute the GetStudent()
method, but frees the calling thread, so that it can execute further statements in the AsyncQueryAndSave
method.
The query.wait()
method holds the execution until the asynchronous method completes. Once it completes, we can get the result using the variable query.Result
.
In the same way, the asynchronous save method is called and gets the result.