2013-04-09 36 views
7

我已經在VS 2012中創建了一個WebApi項目,使用NHibernate作爲我的ORM,並且我打算啓用對它的Odata支持。所以我用一個Get方法創建了一個測試控制器,它從我的數據庫的一個表中返回一個實體列表。WebApi控制器和ODATA限制服務器端結果w/Nhibernate

一切工作正常,我可以使用OData過濾和命令我的結果等問題是我找不到方法來限制從數據庫返回到控制器的數據量,並且此表有數百萬條記錄。

使用Queryable屬性的PageSize屬性僅似乎限制了返回給客戶端的數據量,但沒有限制從數據庫返回的數據量。

我試圖返回之前申請的get方法內的IQueryable一個Take(n),它限制了結果從DB帶回,但它打破了OData的過濾,因爲如果你嘗試查詢這不是一個實體在前n個結果中,它只是返回一個空集合。

我知道你可以使用OData上的$Top參數來完成這個任務,但我不想依賴提供它的客戶端/消費者,以確保我不會不必要地帶來數千甚至數百萬條記錄我不打算使用。

我也試着手動檢查客戶端是否在查詢字符串上提供了Top參數,將OData轉換應用於我的Queryable,然後在轉換後的查詢上應用Take(n)方法。這種方法使我能夠通過OData過濾任何實體,但是它破壞了分頁,因爲如果我使用$Skip=n參數,它將再次返回一個空集合。

那麼,有沒有辦法可靠地限制從數據庫中獲取的結果,同時不會破壞OData支持?

+1

你在OData和NHibernate之間使用什麼橋樑?你是否在將OData轉換爲NHibernate IQueryable或者你在使用庫?另外,在過去,我看到人們會自動對通過API返回的所有結果施加TOP 1000,併發送一些信息,表明他們只收到了部分請求的數據,並且通常會提供一個預先創建的URL,供調用者使用使用它將返回下一個1000個結果。調用者將繼續使用提供的URL,直到他們收到所有數據。 – 2013-04-09 23:25:59

+0

我沒有使用OData直接創建查詢,而是作爲我的客戶端的便捷工具來篩選現有方法的返回結果。所以例如我有一個GetAllProducts()方法,它執行使用Linq到NHibernate的查詢,並且我返回IQueryable。你描述的行爲是在Queryable atribute上使用PageSize屬性時的默認行爲,但正如我在我的帖子中提到的,這隻會限制客戶端所收到的內容,而不會影響從數據庫中獲取到我的服務方法的結果。 – andyroschy 2013-04-10 16:32:35

回答

2

我們最近也發現了這一點。當啓用服務器驅動分頁時,我們不應用Take(pageSize),因爲我們必須確定是否應生成下一頁鏈接。我們只枚舉pageSize實體的結果集並檢查是否有更多的實體。我們認爲大多數提供者通常會帶來一部分結果,因爲IQueryable通常是一個懶惰的實現。結果不是這樣。此外,如果數據庫只知道pageSize需要的結果數量,則可以優化該查詢。

This是爲它打開的問題。好消息是優素福已經修復它:)。這是修復它的commit。所以,如果你抓住夜間建設,你應該是好的。

+0

昨天我看到了這個問題,但是如果你點擊修正鏈接,頁面就會丟失,這給我一個不好的預感。我會盡力得到最新的構建並測試這個來看看這個。 – andyroschy 2013-04-10 16:27:16

+1

看起來像codeplex不再理解部分sha1。無論如何,這個鏈接應該工作https://aspnetwebstack.codeplex.com/SourceControl/changeset/8517d73f5f60ffb3e1c8a590af4695c7bda37709 – 2013-04-10 18:29:10