valverij
valverij

Reputation: 4941

Async LINQ queries null when using Entity Framework 6 with Azure SQL?

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

Answers (2)

Andriy Svyryd
Andriy Svyryd

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

The Memebot
The Memebot

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

Related Questions