首页 > 解决方案 > 带有 EFCore 的 OData - 为什么没有 WHERE 子句?

问题描述

我有一段时间没有搞乱 OData,但我记得它非常有用。所以我为我的 API 选择了 .NetCore 3.1 EFCore + OData 架构。以使其完全通用等。

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

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

很酷,我得到了我期待的 JSON!但是太慢了,为什么呢?查看 SQL (Profiler),我可以看到它没有 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();
        }

标签: api.net-coreodataef-core-3.1

解决方案


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

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

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

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

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


推荐阅读