如何限制OData请求中的数据量?

时间:2013-08-07 17:32:13

标签: asp.net-mvc asp.net-web-api entity-framework-5 odata

我有一个包含76个用户和UserGroups表的Users表。

使用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();
    }

我在this post中读到:

  

实体框架负责构建基于的动态查询   请求。

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

在查询中添加.Take()无法实现所需的结果,因为我们还需要为分页目的返回的实际记录数。

我正在考虑通过ODataQueryOptions使用抓取一些属性,但这似乎也不正确。

我的工作单元和存储库的实现是否与我想要完成的内容不一致,如果是,那么如何纠正?

1 个答案:

答案 0 :(得分:0)

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

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options#server-paging

如果您告诉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;
    }

你的代码不起作用,因为它试图将选项应用到最后一行“users.AsQueryable()”,所以实际发生的是,EF拉出FULL数据集,然后将查询应用到最后一行line(在内存集合中)。这就是为什么你没有看到“过滤器”没有被传递给SQL。

机制就是这样,EF尝试将Query应用到它在代码中找到的IQueryable集合(还有一个问题是如何找到正确的行)。