c# - 需要有关使用 Linq 在循环中添加Where 子句的帮助

标签 c# linq linq-to-entities

下面是我正在尝试做的事情的粗略和简化的代码示例,但它没有按预期工作。我正在使用 Linq to Entity 以防万一。

基本上,如果我有两个日期子句,则 DateClause 的第一个循环最终不会返回任何内容,对于一个日期子句效果很好。在 TextClause 的循环中,它似乎忽略了第一个文本子句之后的每个文本子句。

我的期望是这些子句将 AND 在一起,这样,如果我执行一个文本子句,然后执行另一个,则应该添加它们,并且我会得到更集中的结果,尤其是使用 Contains 方法时。

对日期的期望是我希望能够用它来执行日期范围,但如果有两个日期,它总是不返回任何内容,即使我知道该范围内有包含正确日期的记录。

我确信我做错了什么或者是愚蠢的事情,但我看不到它。

enum Operators
{
    Contains,
    DoesNotContain,
    GreaterThan,
    LessThan
}

public void DoSomething(List<DateClauses> dateClauses, List<TextClauses> textClauses)
{
    var query = from t in context.Table
                where t.Enabled = true
                select new
                {
                    title = t.title
                    date = t.date
                }


    foreach (DateClause clause in dateClauses)
    {
        switch (clause.Operator)
        {
            case Operator.GreaterThan:
                query = query.Where(l => l.date > clause.Date);
                break;
            case Operator.LessThan
                query = query.Where(l => l.date < clause.Date);
                break;
        }       
    }

    foreach (TextClause clause in textClauses)
    {
        switch (clause.Operator)
        {
            case Operator.Contains:
                query = query.Where(l => l.title.Contains(clause.Text));
                break;
            case Operator.DoesNotContain
                query = query.Where(l => !l.title.Contains(clause.Text));
                break;
        }
    }
}

编辑:更新了示例代码以显示流程中枚举的使用。当我将枚举的使用推断到一些非常好的解决方案(否则可以使用 bool 值)时,会导致 Joel 的回复中我的评论中显示异常。

我想说我喜欢到目前为止在回复中看到的内容,并且我已经学到了一些新的 Linq 技巧,我为这个示例表示歉意,因为我认为 bool 与 enum 对 Linq 来说并不重要。我希望这些更改将有助于找到适合我的解决方案。再次感谢您迄今为止的精彩回复。

最佳答案

只是一个大胆的猜测,但是将循环更改为以下内容是否会产生不同的结果?

foreach (DateClause clause in dateClauses)
{
    var capturedClause = clause;
    switch (clause.Operator)
    {
            case Operator.GreaterThan:
                    query = query.Where(l => l.date > capturedClause.Date);
                    break;
            case Operator.LessThan
                    query = query.Where(l => l.date < capturedClause.Date);
                    break;
    }               
}

您正在创建捕获循环变量的Where条件,而不是每次迭代的循环变量的值。因此最终,每个Where将是相同的,使用循环的最后一次迭代的值,因为查询是在最后一次迭代之后执行的。通过引入临时变量,您将捕获每次迭代的变量。

另请参阅 Eric Lippert 的 blog about this subject .

关于c# - 需要有关使用 Linq 在循环中添加Where 子句的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1918401/

相关文章:

c# - 数组的 Lambda 表达式?

c# - 在 LINQ 中,Find 是否优先于 First,反之亦然?

c# - linq distinct 或 group by 多个属性

c# - Entity Framework : Many To Many Count and Sum

c# - 在 MVC 3 中,我无法让 @Html.DisplayFor 呈现格式化字符串

c# - 如何从 WPF TextBlock 中删除额外的填充?

c# - 我域外的客户端可以访问 WCF 服务

c# - 如果使用 LINQ 键存在,则从字典中选择值

c# - 使用 LINQ 聚合对象

javascript - AJAX request.term 返回 null; jQuery 自动完成文本框,.NET MVC