假设我的ApiController中有两种相同方法:
[Route("GetUser1")]
[EnableQuery]
public IHttpActionResult GetUser1(Guid id)
{
var user = _dbContext.Users.Where(u => u.Id == id);
return Ok(user); // IQueryable<User>
}
[Route("GetUser2")]
[EnableQuery]
public async Task<IHttpActionResult> GetUser2(Guid id)
{
var user = await _dbContext.Users.Include("Customer").Where(u => u.Id == id).ToListAsync();
return Ok(user); // List<User>
}
我打了两个电话,得到了相同的结果:
http://localhost:53916/api/User/GetUser1?id=7aa62ba7-98b1-4b7d-94a4-04fb0b41435f&$expand=Customer
http://localhost:53916/api/User/GetUser2?id=7aa62ba7-98b1-4b7d-94a4-04fb0b41435f
它们显然被具体化为同一个SQL查询,带有WHERE子句和JOIN:
...
FROM [GetTruckMobileService].[Users] AS [Extent1]
LEFT OUTER JOIN [GetTruckMobileService].[Customers] AS [Extent2] ON [Extent1].[Customer_Id] = [Extent2].[Id]
WHERE [Extent1].[Id] = @p__linq__0
第一种方法对我来说似乎更灵活,因为不同的客户可以选择他们想要扩展的领域。但我不确定一件事:在执行SQL时,它是否包含线程。第二种方法使用async
,因此它保持线程空闲。在执行I/O操作时,不要让线程忙于等待,这一点很重要,因为这样会很快耗尽IIS线程池中的可用线程。所以,这就是我的问题:如果我选择第一种方法,会导致线程阻塞等待SQL执行吗?
请注意,应用于第二个方法的[EnableQuery]
将是LINQ to Objects,而不是LINQ to Entities,因此如果我想扩展其他字段并在OData查询中传递此意图,$expand
将无法在那里工作。
我也在寻找答案,看起来它是同步的。请检查github问题中的答案。
ysmoradi评论1月16日•
无论何时定义odata操作或函数,都可以返回数据同步或异步,这取决于您的代码,类似于webapi。但是如果您在函数/操作中返回IQueryable应用EnableQuery属性,它应用$filter、$order等,然后它执行IQueryable">sync"以产生响应。这是因为每一个IQueryable提供商,如ef、ef-core、raven-db、mongodb IQueryable提供程序有自己的异步方法,odata是不知道。但是每个IQueryable都可以使用前臂轻松。实际上这是在webapi级别完成的,它不是odata的东西。OData的EnableQuery应用OData查询并离开IQueryable to web api。请注意,当您传递$inlineCount时,odata的EnableQuery执行查询以"同步"的方式获取总计数。它是重要的是要知道odata是一个标准,它没有什么好说的关于同步或异步。我们谈论的是asp.net web api odata此处为"默认值"。您也可以将其配置为异步。