如何使用LINQ生成带有分组OR查询的AND?

时间:2016-03-23 16:15:44

标签: c# entity-framework linq

我正在努力了解如何使用LINQ来提出如下查询...

SELECT *
FROM foo
WHERE a = false AND (b = true OR c = true)

我使用Entity Framework和LINQ来查询我的数据库。我有一个表和实体类,它有一些布尔列,看起来像......

public class Foo
{
  public bool A { get; set; }
  public bool B { get; set; }
  public bool C { get; set; }
}

var foos = DbSet<Foo>();

我正在尝试编写一个查询来选择这些记录,如果我想要包含真实的列,则需要将它们组合在一起,而不是AND&#39; d 。但是,对于不正确的属性,它们需要以AND形式存在。

我确定这是非常基本的东西,但我只是没有看到简单的解决方案。具体来说,我无法弄清楚如何逐步添加OR子句。

编辑:

为了澄清我的逻辑,我将解释我想要实现的目标。我试图编写一个允许我询问数据库的过滤查询,然后向我展示所有的A,其中A为真,或B为真且C不为真&#34;。或者查询可能需要询问,&#34;向我展示C为真的所有Foos,A和B不是真的&#34;。

这是一个用作ASP.NET操作方法的一部分的查询,基于一些复选框进行过滤。因此,action方法知道A,B或C是否需要被过滤为true或false,我只需要编写一个构建此查询的LINQ表达式。

6 个答案:

答案 0 :(得分:2)

LINQ for this几乎与SQL相同:

foos.Where(n => n.A == false && (n.B == true || n.C == true))

答案 1 :(得分:2)

var result = foos.Where(x => !x.A && (x.B || a.C)).ToList();

答案 2 :(得分:1)

  

如果A为真,则需要成为该OR表达式的一部分,否则   它需要成为AND表达式的一部分

您可以使用?运算符。

var result = foos.Where (x => x.A ? x.B && x.C : x.B || x.C);

如果x.A == true语句为x.B && x.C,或x.B || x.C则为

答案 3 :(得分:1)

我不同意buffjape。在你的情况下,我会逐步添加Where子句。我会做类似以下的事情:

//start with the full set
var results = DbSet<Foo>();

//then build the where clause using conditional logic based on which checkboxes are checked

if(aCheckBoxIsChecked)
{
    results = results.Where(foo => foo.A == true); //each where you add is effectively an and
}

if(bCheckBoxIsChecked)
{
    results = results.Where(foo => foo.B == true);
}

... //and keep on with as many checkboxes as you have


if(aCheckBoxIsChecked && cCheckBoxIsChecked)
{
    results = results.Where(foo => foo.B != true);
}
else if(!aCheckBoxIsChecked)
{
    results = results.Where(foo => foo.B == true || foo.C == true);
}
else if(...) //any other clauses
{
    ... //any other logic
}

... //any other tests

/* The key insight, is that Linq will not execute your query until 
you try to access the results. Therefore, you can continue to build
an arbitrarily complex query until you've finished it, and then you
can execute it, as in the below line. */

return results.ToList(); //Execute. Or whatever method you want to use to execute the query.

因此,通过逐步构建我们的子句,您可以完全灵活地构建任意Linq Where子句。

就像我说的那样,我不同意逐渐建立你的where子句是坏的断言。是的,你必须要小心,但是当你的where子句由许多不同的参数驱动时,这种技术可以给你很大的灵活性。

答案 4 :(得分:0)

尝试逐步添加WHERE子句是一个典型的Linq错误:

Binder Framework

相反,总是使用一个where子句:

  var results = foos.Where(n => n.A == false)
                    .Where(n => n.B == true);

  // Bug: testing C == true, but this ignores A
  results = results.Union(foos.Where(n => n.C == true));

如果表达式对于一行而言太大,请切换到查询语法:

  results = foos.Where(n => n.A == false && (n.B == true || n.C == true));

作为最后的手段,如果Where子句变得过长,请使用sql存储过程。

答案 5 :(得分:0)

SELECT *
FROM foo
WHERE a = false AND (b = true OR c = true)

将是

foos.Where(x=>!x.a && (x.b || x.c));

或者你也可以这样做:

foos
  .Where(x=>!x.a)
  .Where(x=>x.b || x.c);