我正在使用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)是可能的。
我在这里缺少什么,伙计们?
答案 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();