查询结果不能多​​次枚举?

时间:2009-09-01 08:28:35

标签: linq-to-sql invalidoperationexception

我正在使用LINQ to SQL在Sql server 2008中获取FullTextSearch存储过程的搜索结果。我将过程从服务器资源管理器拖到设计器,并使用适当的返回类型和参数创建了方法。现在问题是,我需要获取调用此方法的结果的Count,因此使用我的存储库方法(将调用Sproc方法并将结果作为IQueryable返回),我进行以下调用。

var result = repository.FullTextSearch(searchText);
        int resultsCount = result.Count();
        var ret = result.Skip((pageNumber - 1) * PageSize).Take(PageSize).ToList();

每次我尝试运行它时,此代码都会生成一个InvalidOperationException,异常说(是的,你猜对了!)“查询结果不能多​​次枚举。”

为Sproc生成的方法返回ISingleResult,它应该是O.K.据我所知。我需要在我的视图上支持分页,所以我需要知道总页数,如果我能得到所有项目的计数,那么(再次AFAIK)是可能的。

我在这里缺少什么,伙计们?

4 个答案:

答案 0 :(得分:17)

您可以在ToList()之后添加repository.FullTextSearch(searchText)来电。这样,结果将从服务器中检索,之后您可以随意使用它们(因为它们现在已加载到内存中)。

您现在要做的是两次运行相同的SQL查询,效率很低。

答案 1 :(得分:14)

由于这是执行存储过程,所以你所有可爱的Skip / Take在很大程度上都是多余的...它别无选择,只能将所有数据带回来(存储过程调用是非可组合)。它唯一能做的就是没有实现其中一些对象。

我想知道更好的方法是重构代码以进行两次调用:

int result = repository.FullTextSearchCount(searchText);
var result = repository.FullTextSearch(searchText, skip, take); // or similar

即。使分页参数成为SPROC的一部分(以及使用ROW_NUMBER() / OVER(...)进行数据库过滤,或使用表变量,临时表等) - 或者与{{ sproc中的1}}参数:

OUTPUT

(我似乎记得int? count = null; var result = repository.FullTextSearch(searchText, skip, take, ref count); 变为OUTPUT,因为TSQL ref确实是输入+输出)

答案 2 :(得分:5)

使用ToList()有助于避免此问题。

var result = repository.FullTextSearch(searchText).ToList();

答案 3 :(得分:1)

我建议如果你需要计数,先执行结果。然后从列表本身运行计数,因为在结果执行中不使用resultsCount。

var result = repository.FullTextSearch(searchText);
var ret = result.Skip((pageNumber - 1) * PageSize).Take(PageSize).ToList();
int resultsCount = ret.Count();