1 回答
TA貢獻1852條經驗 獲得超1個贊
所以在這種情況下,我確實認為你想要?IQueryable而不是IEnumerable.?最容易記住的方法是將IEnumerable所有數據加載到內存中,然后運行其余的 LINQ 查詢,同時IQueryable嘗試在源上運行過濾器(如果它可以將結果數據加載到內存中)。您確實需要使用支持IQueryableLINQ to SQL 或 Entity Framework 的 ORM。對于 CosmosDB,SDK 構建在 LINQ to SQL 之上。
通過使用你將所有IEnumerable數據從 Cosmos加載到內存中,然后應用你的過濾器和分頁。當您只有幾條記錄時這很好,但是隨著數據集的增長,您可能可以想象這會如何成為一個主要問題。通常,您希望在數據庫中做盡可能多的工作,并且只返回最少數量的結果。這將遠遠超過使用反射構建謂詞的任何性能考慮因素。
的最好的部分之一IQueryable是它繼承自IEnumerable,因此任何與之一起工作的東西都IEnumerable將與IQueryable.?您需要做的就是擺脫您的AsEnumerable().
重要的是要注意,并非所有 LINQ 運算符都自動支持,一旦系統遇到無法翻譯的運算符,它就會執行目前已有的操作,并在內存中完成其余操作。文檔中有CosmosDB 的可用運算符列表。
對于您的查詢,最重要的是,雖然您的Where()條款得到支持,Skip()但Take()目前不支持。這意味著每次執行此方法時,所有結果都將從 CosmosDB 返回,然后對分頁進行評估。
有幾種方法可以在 SDK 中處理分頁。當前支持的方式是將MaxItemCountinside your設置FeedOptions為您的頁面大小。Skip()當前系統使用延續令牌代替函數。為了訪問令牌,您可以使用AsDocumentQuery().?由于您必須逐頁瀏覽到下一頁,因此緩存令牌可能非常有幫助——跳來跳去很困難。
第二種選擇是使用 .Net SDK v3。它目前處于預覽階段,但可在 Nuget 上使用。幾個月前啟用了 skip/take。在這種情況下,在您調用之前的所有內容ToList()都應轉換為 SQL 并在 CosmosDB 中進行評估。
- 1 回答
- 0 關注
- 147 瀏覽
添加回答
舉報
