2013-12-18 36 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个信息。