[英]Linq filtering results with multiple Where clauses
我正在尝试使用EF 5将多个搜索条件应用于结果集(在本例中,用于库目录搜索)。 这是相关代码:
public IQueryable<LibraryResource> GetSearchResults(string SearchCriteria, int? limit = null)
{
List<string> criteria = SearchCriteria.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
IQueryable<LibraryResource> allResults = context.LibraryResources.Include("Type").Where(r => r.AuditInfo.DeletedAt == null);
foreach (string criterion in criteria)
{
allResults = allResults.Where(r => (r.Title.Contains(criterion) || r.Keywords.Contains(criterion) || r.Author.Contains(criterion) || r.Comments.Contains(criterion)));
}
allResults = allResults.OrderBy(r => r.Title);
if (limit.HasValue) allResults = allResults.Take(limit.Value);
return allResults;
}
样本SearchCriteria =“历史时代”
出于某种原因,只应用最后一个标准。 例如,在上面的示例中,返回标题,作者,关键字和注释中具有“时代”的所有书籍,而不会过滤“历史”。 我逐步完成了代码,循环执行了两次,每次都有适当的标准。 你能看到我不能的东西吗? 谢谢!
您已成为修改已结算变量值的牺牲品。
将代码更改为:
foreach (string criterion in criteria)
{
var crit = criterion;
allResults = allResults.Where(/* use crit here, not criterion */);
}
这里的问题是,在构建查询时,您的过滤表达式会关闭变量criterion
,实际上是在评估查询时将其拉入范围。 但是,在那个时候, criterion
只有一个值(它碰巧循环的最后一个),所以除了最后一个过滤器之外的所有过滤器实际上都会变成最后一个过滤器的重复。
创建criterion
的本地副本并引用表达式中的内容会更正问题,因为每次crit
都是一个不同的局部变量,其生命周期不会从循环的一次迭代延伸到下一次迭代。
有关更多详细信息,您可能需要阅读C#是否有理由在foreach中重用变量? ,还提到C#5.0将采取适用于这种情况的重大变化:循环变量criterion
的生命周期将发生变化,使得此代码无需额外的本地即可正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.