动态|如何完成复杂查询的动态构建?

微软中国MSDN 点击上方 蓝字关注我们
有的时候 , 你需要动态构建一个比较复杂的查询条件 , 传入数据库中进行查询 。 而条件本身可能来自前端请求或者配置文件 。 那么这个时候 , 表达式树 , 就可以帮助到你 。 本文我们将通过几个简短的示例来了解如何完成这些操作 。
微软MVP实验室研究员

动态|如何完成复杂查询的动态构建?
文章图片

俞坤 Justin Yu
微软MVP , Dapr中文文档译制小组成员 , 运营有公众号:newbe36524的技术专栏 。
主要从事.net服务端开发 , Blazor浏览器扩展开发两个月半练习生 。
你也可能接到过这些需求:

动态|如何完成复杂查询的动态构建?
文章图片

从模型进行查询

动态|如何完成复杂查询的动态构建?
文章图片

基于配置查询
今天我们看看表达式树如何实现这些需求 。
Where当中可以传入固定的条件
以下是一个简单的单元测试用例 。 接下来 , 我们将这个测试用例改的面目全非 。

[ Test]publicvoidNormal( ){ varre = Enumerable.Range( 0, 10).AsQueryable // 0-9 .Where(x => x >= 1&& x < 5).ToList; // 1 2 3 4 varexpectation = Enumerable.Range( 1, 4); // 1 2 3 4 re.Should.BeEquivalentTo(expectation); } Queryable中的Where就是一种表达式树
由于是 Queryable 的关系 , 所以Where当中的其实是一个表达式 , 那么我们把它单独定义出来 , 顺便水一下文章的长度 。
[ Test]publicvoidExpression00( ){ Expression<Func< int, bool>> filter = x => x >= 1&& x < 5;varre = Enumerable.Range( 0, 10).AsQueryable.Where(filter).ToList; varexpectation = Enumerable.Range( 1, 4);re.Should.BeEquivalentTo(expectation); }【动态|如何完成复杂查询的动态构建?】表达式可以通过Lambda隐式转换
Expression 右侧是一个 Lambda, 所以可以捕获上下文中的变量 。
这样你便可以把 minValue 和 maxValue 单独定义出来 。
于是乎你可以从其他地方来获取 minValue 和 maxValue 来改变 filter 。
[ Test]publicvoidExpression01( ){ varminValue = https://www.sohu.com/a/1;varmaxValue = 5;Expression> filter = x => x >= minValue && x < maxValue;varre = Enumerable.Range( 0, 10).AsQueryable.Where(filter).ToList; varexpectation = Enumerable.Range( 1, 4);re.Should.BeEquivalentTo(expectation); } 可以使用方法创建表达式
那既然这样 , 我们也可以使用一个方法来创建 Expression 。

推荐阅读