2013-08-07 36 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