C# 具有多个Where子句的Linq筛选结果

C# 具有多个Where子句的Linq筛选结果,c#,linq,C#,Linq,我试图使用EF5将多个搜索条件应用于结果集(在本例中,用于库目录搜索)。以下是相关代码: public IQueryable<LibraryResource> GetSearchResults(string SearchCriteria, int? limit = null) { List<string> criteria = SearchCriteria.Split(new char[] { ' ' }, StringSplitOptions.R

我试图使用EF5将多个搜索条件应用于结果集(在本例中,用于库目录搜索)。以下是相关代码:

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;
    }
公共IQueryable GetSearchResults(字符串搜索条件,int?limit=null) { List criteria=SearchCriteria.Split(新字符[]{''},StringSplitOptions.RemoveEmptyEntries.ToList(); IQueryable allResults=context.LibraryResources.Include(“类型”)。其中(r=>r.AuditInfo.DeletedAt==null); foreach(条件中的字符串条件) { allResults=allResults.Where(r=>(r.Title.Contains(criteria)| | r.Keywords.Contains(criteria)| | | r.Author.Contains(criteria)| r.Comments.Contains(criteria)); } allResults=allResults.OrderBy(r=>r.Title); 如果(limit.HasValue)allResults=allResults.Take(limit.Value); 返回所有结果; } 示例SearchCriteria=“历史年代”


出于某种原因,只应用最后一个标准。例如,在上面的示例中,将返回标题、作者、关键字和注释中带有“era”的所有书籍,而不按“历史”进行过滤。我仔细阅读了代码,循环执行了两次,每次都有相应的标准。你能看到一些我看不见的东西吗?谢谢

您已成为修改封闭变量值的牺牲品

将代码更改为:

foreach (string criterion in criteria)
{
    var crit = criterion;
    allResults = allResults.Where(/* use crit here, not criterion */);
}
这里的问题是,当您构建查询时,您的过滤表达式将关闭变量
条件
,实际上是在计算查询的点将其拉入范围。但是,在那时,
标准
将只有一个值(恰好循环的最后一个值),因此除最后一个过滤器外,所有过滤器实际上都将变成最后一个过滤器的副本

创建
criteria
的本地副本并在表达式中引用该副本可以纠正问题,因为
crit
每次都是不同的局部变量,其生存期不会从循环的一次迭代延伸到下一次迭代


要了解更多详细信息,您可能需要阅读,其中还提到C#5.0将采取适用于此场景的突破性更改:循环变量
标准
的生命周期将发生变化,使此代码在没有额外局部变量的情况下正常工作。

此外,您可能需要短路或“Jon,您是明星”。就这样。