C# 用多个where查询

C# 用多个where查询,c#,linq-to-sql,where-clause,C#,Linq To Sql,Where Clause,我需要编写一个查询,在数据库表上执行关键字搜索。代码目前看起来是这样的(尽管有一组硬编码的关键字): 因为关键字迭代器在循环过程中会发生变化,所以我的SQL只包含对最后一个值(“charlie”)的引用 我应该怎么做来避免这个问题?在应用每个新的关键字where子句之前,我可能会将可查询的故事转换为列表,但这似乎效率低下 已解决 谢谢你的回答。最终,我遇到了两个独立的问题,这两个问题都已得到解决: 在foreach()循环中使用局部变量以避免“访问修改的闭包”问题 在LINQKit中使用Pred

我需要编写一个查询,在数据库表上执行关键字搜索。代码目前看起来是这样的(尽管有一组硬编码的关键字):

因为关键字迭代器在循环过程中会发生变化,所以我的SQL只包含对最后一个值(“charlie”)的引用

我应该怎么做来避免这个问题?在应用每个新的关键字where子句之前,我可能会将可查询的故事转换为列表,但这似乎效率低下

已解决

谢谢你的回答。最终,我遇到了两个独立的问题,这两个问题都已得到解决:

  • 在foreach()循环中使用局部变量以避免“访问修改的闭包”问题
  • 在LINQKit中使用PredicateBuilder动态组合OR子句的列表,以允许“任意”样式的关键字搜索

  • 将变量分配给foreach块范围内的临时变量,以便每次都获得一个新变量

    foreach( var keyword in keywords )
    {
        var kwd = keyword;
        stories = from story in stories where story.Name.Contains ( kwd ) );
    }
    

    Eric Lippert有一个(或两个)解释在闭包中包含循环变量的危险以及如何避免它。

    这里有一个非常简单的方法:

    var keywords = new [] { "alpha", "bravo", "charlie" };
    IQueryable<Story> stories = DataContext.Stories;
    
    foreach( var keyword in keywords )
    {
        string kw = keyword;
        stories = from story in stories where story.Name.Contains ( kw ) );
    }
    
    return stories;
    
    var关键字=new[]{“alpha”,“bravo”,“charlie”};
    IQueryable stories=DataContext.stories;
    foreach(关键字中的var关键字)
    {
    字符串kw=关键字;
    故事=故事中的故事,其中story.Name.Contains(kw));
    }
    回归故事;
    
    你也可以考虑

    var keywords = new [] { "alpha", "bravo", "charlie" };
    IQueryable<Story> stories = DataContext.Stories
                                           .Where(story => keywords.All(kw => story.Name.Contains(kw));
    
    var关键字=new[]{“alpha”,“bravo”,“charlie”};
    IQueryable stories=DataContext.stories
    .Where(story=>keywords.All(kw=>story.Name.Contains(kw));
    
    您需要制作关键字的本地副本:

    foreach( var keyword in keywords )
    {
        var localKeyword = keyword;
        stories = from story in stories where story.Name.Contains ( localKeyword ) );
    }
    

    我刚刚解决了部分问题。“访问修改的闭包”很容易用关键字变量的局部范围副本修复,如下所示:

    var keywords = new [] { "alpha", "bravo", "charlie" };
    IQueryable<Story> stories = DataContext.Stories;
    
    foreach( var keyword in keywords )
    {
        var innerKeyword = keyword;
        stories = from story in stories where story.Name.Contains ( innerKeyword ) );
    }
    
    return stories;
    
    var关键字=new[]{“alpha”,“bravo”,“charlie”};
    IQueryable stories=DataContext.stories;
    foreach(关键字中的var关键字)
    {
    var innerKeyword=关键字;
    故事=故事中的故事,其中story.Name.Contains(innerKeyword));
    }
    回归故事;
    

    不幸的是,添加多个where子句可能对我不起作用。每个LINQ表达式都由AND分隔,因此只返回满足所有关键字的故事。我想要有任何关键词的故事。

    我没有尝试过,但是类似的东西有用吗

    from story in stories
    where keywords.All(kw => story.Name.Contains(kw));
    

    编辑:这是不正确的,请参阅下面的注释

    如果您想查找匹配一个或多个关键字而不是所有关键字的故事,正如您在后续回答中所指出的,您应该使用Any操作符。我相信以下查询(未经测试)会起作用:

    IQueryable<Story> matchingStories = 
        from story in stories
        where keywords.Any(keyword => story.Name.Contains(keyword));
    
    IQueryable匹配存储区=
    从故事到故事
    其中keywords.Any(keyword=>story.Name.Contains(keyword));
    
    +1表示快速手指;)有关更多信息,请查看和/或之前提出的问题,在此处或ScottGu的博客上查找有关动态SQL的文章…任何内容似乎都不起作用。我得到了一个NotSupportedException:“除了Contains()操作符外,查询操作符的LINQ到SQL实现中不能使用本地序列。”啊,对不起,我应该在键入之前考虑一下。。。您需要研究LinqKit及其谓词生成器。查看本页,第二个代码片段正是您想要的:我尝试通过AsQueryable()将字符串列表转换为可查询的,这在执行query.PredicateBuilder时导致了堆栈溢出异常。我正在下载LINQKit.dll。
    from story in stories
    where keywords.All(kw => story.Name.Contains(kw));
    
    IQueryable<Story> matchingStories = 
        from story in stories
        where keywords.Any(keyword => story.Name.Contains(keyword));