【问题标题】:Chaining Linq Where clauses链接 Linq Where 子句
【发布时间】:2015-09-30 09:57:33
【问题描述】:

如何根据不同的变量状态在 linq 中链接“Where”子句。 E,g;年龄范围复选框(21-30、31-40、41-50、51-60、60 >)

我们有一个List<People>‘People’,我们需要根据复选框对其进行过滤。假设 List 不能只是一个 IEnumerable,因为它已经被评估了

除了这样做:

List<People> filteredPeople = new List<people>();
if(CB1.checked)
    filteredPeople = filteredPeople.Union(People.Where(inTheirTwenties))  //assuming method  inTheir20s filters correct  
if(CB2.checked)
    filteredPeople = filteredPeople.Union(People.Where(inTheirThirties)) ;
//...and so on

有没有更好的方法解决这个问题?

【问题讨论】:

  • 为什么是Union?可以直接应用Where方法filteredPeople = filteredPeople.Where(p =&gt; p.Age &gt;=21 &amp;&amp; p.Age &lt;=30)
  • 一个列表实现了IEnumerable,实际上有很多视图集合没有。所以它可以而且是它是否已经被评估过。你在想IQueryable
  • 这段代码被破坏了。同时检查 CB1 和 CB2 不会返回 20s 和 30s。由于您在通话之间更改filteredPeople。事实上,您的代码目前返回所有 People 无论如何。

标签: c# linq linq-to-objects


【解决方案1】:

我会将这一切捆绑到一个 Where 语句中,并更新 inTheirTwenties 方法以像这样对待个人:

filteredPeople.Where(x => (CB1.checked && inTheirTwenties(x)) 
|| (CB2.checked && inTheirThirties(x)) ...);

【讨论】:

  • 如果我们可以选中多个复选框,这将不起作用?
  • @tichra 应该这样做,因为我们通过将 x 传递给 inTheirTwenties 方法一次只评估一个对象,并且我们将不同的检查与||s 结合起来
  • 谢谢,如果没有检查,我假设它将返回空而不是全部?
  • @tichra 没错,如果您想在没有检查的情况下返回所有这些,您可以添加对 || (!CB1.checked &amp;&amp; !CB2.checked ...) 的检查。
  • 除了在前一行编写单独的 if 语句之外,您认为返回所有内容的最佳方法是什么?
【解决方案2】:

链接未知数量的使用OR.Where() 子句会导致代码冗长且难以阅读。幸运的是,在您的场景中,您可以将其反转为一系列 AND 表达式,从而呈现出更具可读性的一批代码。

var filteredPeople = new List<Person>();

if(!checkBox1) filteredPeople = filteredPeople.Where(p => !inTheirTwenties(p));
if(!checkBox2) filteredPeople = filteredPeople.Where(p => !inTheirThirties(p));

如果这是一个 LINQ-to-SQL 查询,这种类型的代码还可以通过创建一个优雅的 WHERE 子句来简化传递到数据库的内容,而无需通过网络发送许多 truefalse。当然,您不能使用inTheirTwenties(Person) 访问 SQL Server,而是可以执行以下操作:

filteredPeople.Where(p => !(p.Age >= 21 && p.Age <=30));

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多