最近在做一个webAPI 的时候遇到一个需要合并多个predicate条件的问题,下面就是对题的情况。为了方便交流我对case进行了简化,请先看如下代码:

using System.Collections.Generic;
using System.Linq; namespace CombineLinqPredicates
{
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
} class Program
{
static void Main(string[] args)
{
var customers = GetCustomers(); var filterCustomers = customers.Where(x => x.Id == );
} private static IEnumerable<Customer> GetCustomers()
{
return new List<Customer>()
{
new Customer(){Id=,Name="Alibaba",Url= "http://www.taobao.com"},
new Customer(){Id=,Name="Jd",Url= "http://www.jd.com"},
new Customer(){Id=,Name="Tencent",Url= "http://www.qq.com"}
};
}
}
}

代码非常简单,一个customer 对象有三个属性,id, name 和 url.  和一个过去customer list的方法 GetCustomers.

在Main方法中, 我通过

var filterCustomers = customers.Where(x => x.Id == 2); 

获取了所有id = 2 的customer 对象。

假如现在 where 条件中的 ID 需要从 UI 获取,而且我需要再添加一个 条件,比如url 中包含 jd 字符串如何做呢?

代码可能变成:

            int? inputCustomerId = null;
string inputUrl = null;
var customers = GetCustomers();
//从UI获取值并填充到 inputCustomerId,inputUrl, 这个过程我们省略。
var filterCustomers = customers;
if (inputCustomerId.HasValue) filterCustomers = filterCustomers.Where(x => x.Id == inputCustomerId.Value);
if (!string.IsNullOrEmpty(inputUrl)) filterCustomers = filterCustomers.Where(x => x.Url.Contains(inputUrl));

在上面的代码中有两次过滤,为了避免这个问题,提高性能,我们需要合并这两个where 条件。

首先我们看下where 条件的定义:

 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

  他的参数类型是 Func<TSource, bool>型的,因此我么可以定义一个类型如下,然后进行合并,具体代码如下:

            Func<Customer, bool> idFilter = x => inputCustomerId.HasValue && x.Id == inputCustomerId.Value;
Func<Customer, bool> urlFilter = x => !string.IsNullOrEmpty(inputUrl) && x.Url.Contains(inputUrl);
Func<Customer, bool> filter = x => true && idFilter(x) && urlFilter(x); filterCustomers = customers.Where(filter);

这样处理后,就解决了二次过滤的问题。

linq中如何合并多个predicate条件的更多相关文章

  1. 2.4 LINQ中使用where子句指定筛选条件

    本篇讲解的内容有: 使用where筛选过滤LINQ查询 带逻辑的where筛选 多个where筛选子句 [1.使用where筛选过滤LINQ查询] 通常一个LINQ查询不会如前面的示例代码这么简单,经 ...

  2. LinQ中合并、连接、相交、与非查询

    LinQ中Union合并查询:连接不同的集合,自动过滤相同项:延迟.即是将两个集合进行合并操作,过滤相同的项 var cities = (from p in mylinq.System_Places ...

  3. Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)

    为了提高开发者的易用性,Rafy 领域实体框架在很早开始就已经支持使用 Linq 语法来查询实体了.但是只支持了一些简单的.常用的条件查询,支持的力度很有限.特别是遇到对聚合对象的查询时,就不能再使用 ...

  4. linq中的contains条件

    linq中的contains条件   在sql查询语句中,in 在linq 中用contains,并且contains前面是数组,而后面是列名,如: SELECT distinct BH FROM c ...

  5. linq中如何实现多个条件的联合查询

    目前接触处理数据这一块比较多,在处理内存中的数据源的时候我一般使用的是linq,linq使用起来像sql语句一样,用法简单,功能强大. 最近需要实现一个从两个不同的文件读取不同的数据,然后根据这两个数 ...

  6. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

  7. 转载Linq中GroupBy方法的使用总结

    Group在SQL经常使用,通常是对一个字段或者多个字段分组,求其总和,均值等. Linq中的Groupby方法也有这种功能.具体实现看代码: 假设有如下的一个数据集: public class St ...

  8. Linq中join & group join & left join 的用法

    Linq中join & group join & left join 的用法 2013-01-30 11:12 12154人阅读 评论(0) 收藏 举报  分类: C#(14)  文章 ...

  9. 简述Linq中.ToList(), .AsEnumerable(), AsQueryable()的区别和用法

    [TOC] 这3个方法的功能完全不同, 应按照具体业务场景使用. AsQueryable() 先说说什么是 IQueryable IQueryable 是当前的 data provider 返回的类型 ...

随机推荐

  1. 【Flutter学习】之深入浅出 Key

    一,前言 在开发 Flutter 的过程中你可能会发现,一些小部件的构造函数中都有一个可选的参数——Key.在这篇文章中我们会深入浅出的介绍什么是 Key,以及应该使用 key 的具体场景. 二,什么 ...

  2. AcWing 224. 计算器 (BSGS算法)打卡

    题目:https://www.acwing.com/problem/content/226/ 题意:有一个计算器能完成三种功能 1.给定Y,Z,P,计算YZModPYZModP 的值: 2.给定Y,Z ...

  3. 让vue用于小程序setData方法

    setData:function(obj){ let that = this; let keys = []; let val,data; Object.keys(obj).forEach(functi ...

  4. PHP浮点计算结果返回异常问题

    php中如果直接小数点进行计算的话.比如16.8*3var_dump是50.4.但是return就变成了50.400000000000006.至于是什么原因本人尚不得而知.解决方法是用把计算放入下面的 ...

  5. centos为用户添加sudo功能

    su chmod a+w /etc/sudoers vim /etc/sudoers [找到root ALL=(ALL) ALL这行] 复制出新的一行,并且将root改为daniel(当前用户名) c ...

  6. Pandas Series数据结构基本操作

    >>> import pandas >>> import numpy as np >>> from pandas import Series,Da ...

  7. docker x509: certificate has expired or is not yet valid

    系统环境:centos 6.5 内核版本:2.6.32-696.1.1.el6.x86_64 程序版本:Docker version 1.7.1, build 786b29d/1.7.1 问题:下载镜 ...

  8. mysql 5.7.20 取得动态sql执行结果

    drop procedure test; delimiter ;; CREATE procedure test() -- 取动态sql的值 begin ); ); set v_sqlcounts = ...

  9. tar 和gzip 的区别

    首先要 弄清两个概念:打包和压缩. 打包是指将一大堆文件或目录什么的变成一个总的文件, 压缩则是将一个大的文件通过一些压缩算法变成一个小文件. 为什么要区分这两个概念呢?其实这源于Linux中的很多压 ...

  10. chrome表单禁止自动填充密码

    在用户登录成功以后,chrome会提示用户记住密码. 用户退出以后若前往注册.忘记密码页时会自动填充密码. 若不希望自动填充密码,只需在input里设置autoComplete="new-p ...