2013-12-18 93 views
0

有沒有什麼辦法可以避免「查詢的結果不能枚舉多次」異常而不使用ToList()?EF 6:查詢的結果不能被枚舉超過一次

這裏是我的代碼的簡化版本:

var entities = _db.Trades.Where(t => t.A > 10); 
int totalCount = entities.Count(); 
entities = entities.Where(t => t.B > 10); 
int totalCountAfterAdditionalFilter = entities.Count(); 

我不能調用ToList()由於性能方面的考慮。我知道我可以再生成一個IQueryable,但這似乎是錯誤的(我有更多像這樣的過濾器)。我可以在第一次調用Count()後保存/複製IQueryable嗎?

謝謝!

+0

「由於性能方面的考慮,我無法調用ToList()」是什麼性能考慮因素?該查詢需要在某個時間點實現 - 爲什麼不在「List」中? –

+0

我有1M +記錄。在這個階段將所有內容加載到內存似乎是錯誤的。在應用最終過濾器之前,我只想獲得計數。一旦過濾完成,我將實現查詢,它將只返回10條左右的記錄。 – SoftwareFactor

+0

您是否真的需要知道這兩個問題,或者您是否需要知道是否有物品被過濾掉?你可以過濾't.B <= 10',如果有任何項目,這兩個不一樣,你有你的答案。如果你真的需要完整的計數,那麼這是行不通的。 – Servy

回答

3

不,你不能達到你想要的結果。作爲替代方案,你可以,但是,保存您的過濾器變量,然後根據需要撰寫他們:

Func<Trade, bool> filter1 = t => t.A > 10; 
Func<Trade, bool> filter2 = t => t => t.B > 10; 
Func<Trade, bool> compositeFilter = t => filter1(t) && filter2(t); 

int totalCount = _db.Trades.Count(filter1); 
int totalCountAfterAdditionalFilter = _db.Trades.Count(compositeFilter); 

//Need more? 
compositeFilter = t => compositeFilter(t) && t.C > 100; 
int totalAfterMoreFilters = _db.Trades.Count(compositeFilter); 
+2

不要將過濾器'Func'包裝在LINQ to Entities使用它們的'Expression '中? – danludwig

+0

問題是我有兩個以上的過濾器,有些不應該有時觸發。但我喜歡你的想法。也許我需要找到一種方法來動態生成表達式,將其保存到一個變量然後重用它。 – SoftwareFactor

0

可能是:

Trades.Where(x => x.A > 10).Select(x => new { i = 1, j = x.B > 10 ? 1 : 0}). 
    GroupBy(y => y.i). 
    Select(g => new { c = g.Count(), = g.Sum(z => z.j)}) 

這是給你一個查詢2個信息。