Reputation: 4941
I have a web application that I recently moved to Azure. In it I have quite a few queries that use EF's async LINQ extensions (examples below). Since migrating to Azure, however, I have noticed that not only are some of these queries returning null
, but MiniProfiler isn't even registering them:
// returns null. No queries logged in MiniProfiler
var someUser = await context.Users.FirstOrDefaultAsync(x => x.Id == id)
// works 100% as expected
var someUser = context.Users.FirstOrDefault(x => x.Id == id)
I've also tried "tricking" it by calling .ToListAsync().FirstOrDefault()
. Of course, this didn't work either.
For what it's worth, this app uses .NET 4.5 and EF6. It has also been running in a traditionally-hosted production environment for ~18 months.
I'm sure this has been answered somewhere, but I've been having a tough time finding any information on it.
EDIT: The id
in the example above is actually coming from a separate method that gets the current user id from the current principal:
// .GetUserId() is an extension method to get the userid from the principal
// Works with SQL Server
// Does not work with Azure SQL
var someUser = await context.Users.FirstOrDefaultAsync(x => x.Id == HttpContext.Current.GetUserId());
To fix this, I pulled that call out:
var userId = HttpContext.Current.GetUserId();
var someUser = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);
Still, though, does anyone know why this works with traditional SQL Server, but not when connecting to an Azure SQL database?
Upvotes: 2
Views: 1565
Reputation: 2041
When executing async code EF6 uses .ConfigureAwait(false)
to prevent deadlocks, so the continuation (the method body after the await) is no longer guaranteed to execute the same thread.
When running on a local SQL Server the time the thread is blocked is usually below some threshold and therefore the continuation is executed synchronously to avoid context switching. However SQL Azure has more latency and triggers proper asynchronous execution resulting in the context being lost in this case.
ASP.NET only sets HttpContext.Current
on the request thread, so when EF evaluates the lambda on the thread pool thread it will be null.
Upvotes: 4
Reputation: 3549
Have you tried putting the "ToListAsync" at the end of the query? I believe the malfunction may be there because of the LINQ deferred execution
Upvotes: 0