Async in Entity Framework 6.0

Tuesday, August 28, 2012

If you pull the latest Entity Framework source from CodePlex, you can take a look at some of the features being added for the next version of EF. These features include an async API for DbContext (SaveChangesAsync and ExecuteSqlCommandAsync), as well as async operations on IQueryable<T> through some new extension methods.

Here is how the async version of SaveChanges looks in an ASP.NET MVC controller action:

[HttpPost]
public async Task<ActionResult> Edit(Thing thing)
{
if(ModelState.IsValid)
{
_db.Entry(thing).State = EntityState.Modified;
await _db.SaveChangesAsync();
return RedirectToAction("Index");
}

return View(thing);
}

The new IQueryable operators are async versions of operators that materialize a concrete result. For example, finding a single entity:

[HttpGet]
public async Task<ActionResult> Edit(int id)
{
var model = await _db.Things.FindAsync(id);
// or
var model = await _db.Things.SingleAsync(t => t.Id == id);

return View(model);
}

Also forcing execution with ToList:

public async Task<ActionResult> Index()
{
var model = new HomeIndexViewModel();
model.Things = await _db.Things.ToListAsync();

return View(model);
}

Getting an application up and running with EF 6 (including migrations) is slightly challenging, but I've found the easiest approach is to msbuild the Nuget.proj file in the NuGet directory, then adding the NuGet\bin\debug directory as a custom local NuGet repository and adding references to EF 6 via NuGet. I also had to register all the EF assemblies for verification skipping with sn -Vr.


Comments
gravatar Jim Wooley Tuesday, August 28, 2012
I have to wonder if there would be an interest in an IObservable<T> or IAsyncEnumerable<T> implementation where values are streamed out to clients as they are received from the database rather than the async but blocked "await" implementation which brings in the entire table as a single chunk.
gravatar scott Tuesday, August 28, 2012
Yes, might be something to combine with SignalR.
gravatar James Hancock Wednesday, August 29, 2012
Here here! Fire hose like a Data Reader would be fantastic! Maybe a foreachasync, or AsEnumeratorAsync or something that let you iterate through the resultset as it pumped. This would seriously speed up A LOT of operations.

It would be even better if it dumped the results as .MoveNext() occurred so that memory wasn't used for the entire resultset. This would be absolutely fantastic for those scenarios where you didn't need to keep it in memory.
gravatar Diego Vega Friday, September 14, 2012
Nice post Scott! Installing nightly builds should be easier really soon. By the eau, the ForEachAsync extension method for streaming results asynchronously is already available in EF6.
gravatar Bohdan Monday, September 24, 2012
One day .NET 4.5 will be approved by big enterprises and then we will start to use it there. Startups and small companies are only who can enjoy using it tight now.

I'm wondering why do we have to mark method as "async" if compiler can do it automatically for us by detecting "await" in the body of the method.
gravatar scott Monday, September 24, 2012
@Bohdan: Good question, here is a good read: blogs.msdn.com/.../whither-async.aspx
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!