【发布时间】:2016-08-10 07:56:33
【问题描述】:
我有一个最近迁移到 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 个月。
我确信这已经在某个地方得到了回答,但我一直很难找到有关它的任何信息。
编辑:上面示例中的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 数据库时却不行?
【问题讨论】:
-
第一种方法,是不是整个调用栈都使用Async?
-
@ErikPhilips 是的,在这种情况下,整个调用堆栈都是异步的。它来自异步 MVC 操作
-
@valverij - 在该方法的任何地方或对该请求中的其他方法的调用中是否有任何
Task<T>.Result调用?您是否尝试过使方法尽可能简单,除了 mvc Action 主体中的return await context.Users.ToListAsync();? -
@Igor 哇,我现在感觉很笨。因此,那里的 id 实际上 来自 HttpContext,它在从异步查询中调用时返回 null。我注意到这种情况偶尔会发生(我知道为什么会发生),并且会定期将其取出。以前在使用 SQL Server 时不会发生这种情况。您知道 Azure SQL 为何如此吗?仅仅是底层 EF SQL 提供程序的不同吗?
-
@valverij - 不确定,但显然 http 上下文没有传递到 Sql Azure 正在执行的异步调用,可能是因为它也使用 http 进行连接?
标签: c# entity-framework azure async-await azure-sql-database