将Entity Framework 6与Azure SQL一起使用时,异步LINQ查询为null

本文关键字:异步 LINQ 查询 null Framework Entity Azure 一起 SQL | 更新日期: 2023-09-27 17:59:40

我有一个最近移动到Azure的web应用程序。在它中,我有很多使用EF的异步LINQ扩展的查询(下面的示例)。然而,自从迁移到Azure后,我注意到这些查询中不仅有一些返回null,而且MiniProfiler甚至没有注册它们:

// 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)

我也试过通过调用.ToListAsync().FirstOrDefault()来"欺骗"它。当然,这也没用。

值得一提的是,这个应用程序使用了.NET 4.5和EF6。它也已经在传统的托管生产环境中运行了大约18个月。

我确信这个问题已经在某个地方得到了答案,但我一直很难找到任何关于它的信息


EDIT:上例中的id实际上来自一个单独的方法,该方法从当前主体获取当前用户id:

// .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());

为了解决这个问题,我调出了那个电话:

var userId = HttpContext.Current.GetUserId();
var someUser = await context.Users.FirstOrDefaultAsync(x => x.Id == userId);

不过,有人知道为什么这适用于传统的SQL Server,但在连接到Azure SQL数据库时却不适用吗?

将Entity Framework 6与Azure SQL一起使用时,异步LINQ查询为null

执行异步代码EF6时使用.ConfigureAwait(false)来防止死锁,因此continuation(等待后的方法体)不再保证执行同一线程。

在本地SQL Server上运行时,线程被阻塞的时间通常低于某个阈值,因此会同步执行延续以避免上下文切换。然而,SQL Azure有更多的延迟,并触发适当的异步执行,导致上下文在这种情况下丢失。

ASP.NET只在请求线程上设置HttpContext.Current,因此当EF计算线程池线程上的lambda时,它将为null。

您是否尝试将"ToListAsync"放在查询的末尾?我认为故障可能是由于LINQ延迟执行