Asynchronous Querying and Saving in EF 6:

Asynchronous execution has been introduced in .NET 4.5 which can be useful in Entity Framework. EF 6 has the ability to execute a query and command asynchronously using an instance of DbContext.

Let's see how to execute asynchronous query first and then we will see an asynchronous call to context.SaveChanges.

Asynchronous Query:

The following is an example of async method which executes 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 async keyword which makes it asynchronous method. The return type of asynchrounous method must be Task<T>. The GetStudent() returns an object of Student entity, so return type must be of Task<Student> type.

Also, LINQ query is marked with await keyword. This frees up the calling thread to execute other code until it executes the query and returns the result. We have used FirstOrDefaultAsync async extension method to get the result. You may use other async methods appropriately such as SingleOrDefaultAsync, ToListAsyn etc.

Asynchronous Save:

EF API providesSaveChangesAsync() 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...");
    }
}

Getting async Query Result:

The following example demonstrates executing async query and get the result and also save 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);
}
Output
Start GetStudent...
Do something else here till we get the query result..
Finished GetStudent...
Start SaveStudent...
Do something else here till we save a student..
Finished SaveStudent...
Saved Entities: 1

In the above example, the async method GetStudent() is called and store the reference in query variable. This will start to execute the GetStudent() method, but frees the calling thread, so that it can execute further statement in AsyncQueryAndSave method. The query.wait() method holds the execution until asynchronous method completes. Once it completes, we can get the result using the variable query.Result. The same way, asynchronous save method is called and get the result.