带有 EFCore 的 OData - 为什么没有 WHERE 子句?

OData with EFCore - why no WHERE clause?

我有一段时间没有弄乱 OData,但我记得它真的很有用。所以我为我的 API 选择了 .NetCore 3.1 EFCore + OData 架构。为了让它完全通用等等等等

做一点测试,我可以从我的浏览器中得到预期的结果:例如

https://localhost:44310/things?someidfield=44

很酷,我回来了 JSON 我期待的!但是速度太慢了,为什么呢?查看 SQL(探查器)我可以看到它没有 WHERE 子句,它从数据库中获取所有内容并在内存中过滤,在 50 万条记录上?

我在这里错过了什么?我已经尝试了多种方法来编写 GET 方法。从不传递任何 queryOptions(有效!但下面的结果相同)开始,然后在下面我明确地将选项应用到 EFCore 实体。

        [HttpGet]
        [EnableQuery]
        public async Task<IEnumerable<thing>> GetThingsAsync(ODataQueryOptions<thing> queryOptions)
        {
           return await queryOptions.ApplyTo(DB.thing).Cast<thing>().ToListAsync();
        }

正在将结果集加载到内存中,因为您正在调用 ToListAsync() 并返回一个 IEnumerable。

如果您的 GetThingsAsync 方法 returns 是 IQueryable<T>(而不是 IEnumerable<T>),则查询将应用于数据库,并且只会获取过滤后的数据。

如果 DB.thing 是一个 EFCore DbSet(实现 IQueryable<T>),那么您可以将您的方法简化为

[HttpGet]
[EnableQuery]
public Task GetThingsAsync()
{
  return DB.thing;
}

此外,就像已经提到的评论中的某些内容一样,在您的情况下正确的过滤语法是 ?$filter=someidfield eq 44