2013-08-07 37 views
0

我有76个用户和UserGroups表的用户表。如何限制来自OData请求的数据量?

使用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来抓取一些属性,但这看起来不太正确。

我的工作单位和存储库的实现与我正在努力完成的工作有关吗?如果是的话,这个问题怎么解决?

回答

0

简单 - 只要将页面大小设置为可查询atrribute [可查询(每页= 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拉完整数据集,然后将查询应用到最后一行(即内存集合中)。这就是为什么你没有看到“过滤器”没有传递给SQL。

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

+0

我看到这是如何工作的,并为下一组数据提供了url,但是,在查看SQL Profiler时,所有请求都是针对所有数据的。也许如果有人可以解释这个机制,以及如何不是所有的数据被返回然后过滤? – ElHaix

+0

好的,但是对于您发布的代码,options.ApplyTo()括号内的代码存在问题:参数类型'System.Linq.IOrderedEnumerable '不能分配给参数类型'System .Linq.IQueryable”。添加.AsQueryable);在OrderBy的最后修复它,但仍然返回类型不正确。 – ElHaix

+0

另外,除此之外,假设我们只从数据库中获得10条记录,是否有后续调用或部分调用来检索记录总数? – ElHaix