Asp.net mvc 如何限制OData请求中的数据量?

Asp.net mvc 如何限制OData请求中的数据量?,asp.net-mvc,asp.net-web-api,entity-framework-5,odata,Asp.net Mvc,Asp.net Web Api,Entity Framework 5,Odata,我有一个76个用户的用户表和用户组表 使用MVC、OData、通用存储库和EF,我试图在基于用户组进行筛选时优化数据检索: /api/Users?$filter=USERGROUPS/any(usergroup: usergroup/ID eq 'Group1') 在客户端,我得到了正确的用户数-71(因为OData根据结果进行过滤),但是我想限制从实际查询返回的记录数-即,我不想返回所有记录,然后再进行过滤(对于非常大的数据集来说,这不是最优的) 我的API控制器方法如下: [Que

我有一个76个用户的用户表和用户组表

使用MVC、OData、通用存储库和EF,我试图在基于用户组进行筛选时优化数据检索:

/api/Users?$filter=USERGROUPS/any(usergroup: usergroup/ID eq 'Group1')
在客户端,我得到了正确的用户数-71(因为OData根据结果进行过滤),但是我想限制从实际查询返回的记录数-即,我不想返回所有记录,然后再进行过滤(对于非常大的数据集来说,这不是最优的)

我的API控制器方法如下:

    [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<USER> Get()
    {
        var unitOfWork = new ATMS.Repository.UnitOfWork(_dbContext);

        var users = unitOfWork.Repository<USER>()
                              .Query()
                              .Include(u => u.USERGROUPS)
                              .Get()
                              .OrderBy(order => order.USERNAME);

        unitOfWork.Save();      // includes Dispose()

        return users.AsQueryable();
    }
[Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]
公共IQueryable Get()
{
var unitOfWork=new ATMS.Repository.unitOfWork(_dbContext);
var users=unitOfWork.Repository()
.Query()
.Include(u=>u.USERGROUPS)
.Get()
.OrderBy(order=>order.USERNAME);
unitOfWork.Save();//包含Dispose()项
返回users.AsQueryable();
}
我在信中读到:

实体框架负责基于 请求

但是,使用SQL Server探查器执行的查询请求的是所有记录,而不是经过筛选的查询

将.Take()添加到查询中并不能获得所需的结果,因为我们还需要为分页目的返回的实际记录数

我曾考虑使用ODataQueryOptions获取一些属性,但这似乎也不太正确


我的工作单元和存储库的实现是否不正确,与我试图完成的工作相关,如果是,如何纠正?

简单-只需设置可查询属性的页面大小[Queryable(PageSize=10)]

如果你告诉EF在哪里应用这些选项,它就会起作用。 像这样:

    //[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<USER> Get(ODataQueryOptions<USER> options)
    {

        var users = options.ApplyTo(_dbContext.Set<USER>()
                              .Query()
                              .Include(u => u.USERGROUPS)
                              .Get()
                              .OrderBy(order => order.USERNAME));

        return users;
    }
/[Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]
公共IQueryable获取(ODataQueryOptions选项)
{
var users=options.ApplyTo(_dbContext.Set())
.Query()
.Include(u=>u.USERGROUPS)
.Get()
.OrderBy(order=>order.USERNAME));
返回用户;
}
您的代码不起作用,因为它试图将选项应用到最后一行“users.AsQueryable()”,所以实际发生的情况是,EF提取完整的数据集,然后将查询应用到最后一行(这是内存中的集合)。这就是为什么您没有看到“过滤器”没有被传递到SQL


机制是这样的,EF试图将查询应用到它在代码中找到的IQueryable集合(仍然存在一个问题,它如何找到正确的行)。

我看到了这是如何工作的,以及为下一组数据提供的url,但是,在查看SQL Profiler时,所有请求都是针对所有数据的。也许有人能解释一下这种机制,以及不是所有的数据都是如何返回然后过滤的?好的,但是对于您发布的代码,选项中的代码有问题。ApplyTo()括号:参数类型“System.Linq.iorderenumerable”不可分配给参数类型“System.Linq.IQueryable”。添加。AsQueryable);OrderBy在结束时修复了它,但返回类型仍然不正确。此外,假设我们只从db返回10条记录,是否有后续调用或调用的一部分来检索记录的总数?嗯,这就是答案——您的问题就是解决方案的答案:)您只能将筛选器应用于Iqueryable集合。这就是IEnumerable和Iqueryable之间的主要区别,如果您可以使用DBContext中返回Iqueryable的smth,那么您就可以了。如果使用Ienumerable作为源,那么所能做的就是在内存中过滤数据集。