在FreeSql源码中Expression表达式拼接默认最多支持到5个泛型参数,当我们使用表关联比较多的时候,就需要进行扩展。



新建一个类,将命名空间改为System.Linq.Expressions,并加入参数扩展

namespace System.Linq.Expressions
{
static partial class LambadaExpressionExtensions
{
//如需扩展增加泛型参数即可
#region T1, T2, T3, T4, T5 ,T6
/// <summary>
/// 使用 and 拼接两个 lambda 表达式
/// </summary>
/// <returns></returns>
public static Expression<Func<T1, T2, T3, T4, T5, T6, bool>> And<T1, T2, T3, T4, T5, T6>(this Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp1, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp2) => And(exp1, true, exp2);
/// <summary>
/// 使用 and 拼接两个 lambda 表达式
/// </summary>
/// <param name="exp1"></param>
/// <param name="condition">true 时生效</param>
/// <param name="exp2"></param>
/// <returns></returns>
public static Expression<Func<T1, T2, T3, T4, T5, T6, bool>> And<T1, T2, T3, T4, T5, T6>(this Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp1, bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp2) => (Expression<Func<T1, T2, T3, T4, T5, T6, bool>>)InternalAndOrExpression(condition, exp1, exp2, true);
/// <summary>
/// 使用 or 拼接两个 lambda 表达式
/// </summary>
/// <returns></returns>
public static Expression<Func<T1, T2, T3, T4, T5, T6, bool>> Or<T1, T2, T3, T4, T5, T6>(this Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp1, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp2) => Or(exp1, true, exp2);
/// <summary>
/// 使用 or 拼接两个 lambda 表达式
/// </summary>
/// <param name="exp1"></param>
/// <param name="condition">true 时生效</param>
/// <param name="exp2"></param>
/// <returns></returns>
public static Expression<Func<T1, T2, T3, T4, T5, T6, bool>> Or<T1, T2, T3, T4, T5, T6>(this Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp1, bool condition, Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp2) => (Expression<Func<T1, T2, T3, T4, T5, T6, bool>>)InternalAndOrExpression(condition, exp1, exp2, false);
/// <summary>
/// 将 lambda 表达式取反
/// </summary>
/// <param name="exp"></param>
/// <param name="condition">true 时生效</param>
/// <returns></returns>
public static Expression<Func<T1, T2, T3, T4, T5, T6, bool>> Not<T1, T2, T3, T4, T5, T6>(this Expression<Func<T1, T2, T3, T4, T5, T6, bool>> exp, bool condition = true) => (Expression<Func<T1, T2, T3, T4, T5, T6, bool>>)InternalNotExpression(condition, exp); #endregion #region 通用表达式方法
static LambdaExpression InternalAndOrExpression(bool condition, LambdaExpression exp1, LambdaExpression exp2, bool isAndAlso)
{
if (condition == false) return exp1;
if (exp1 == null) return exp2;
if (exp2 == null) return exp1; var newParameters = exp1.Parameters.Select((a, b) => Expression.Parameter(a.Type, a.Name /*$"new{b}"*/)).ToArray(); var left = new NewExpressionVisitor(newParameters, exp1.Parameters.ToArray()).Replace(exp1.Body);
var right = new NewExpressionVisitor(newParameters, exp2.Parameters.ToArray()).Replace(exp2.Body);
var body = isAndAlso ? Expression.AndAlso(left, right) : Expression.OrElse(left, right);
return Expression.Lambda(exp1.Type, body, newParameters);
}
static LambdaExpression InternalNotExpression(bool condition, LambdaExpression exp)
{
if (condition == false) return exp;
if (exp == null) return null; var newParameters = exp.Parameters.Select((a, b) => Expression.Parameter(a.Type, a.Name /*$"new{b}"*/)).ToArray();
var body = Expression.Not(exp.Body);
return Expression.Lambda(exp.Type, body, newParameters);
}
internal class NewExpressionVisitor : ExpressionVisitor
{
ParameterExpression[] _newParameters;
ParameterExpression[] _oldParameters;
public NewExpressionVisitor(ParameterExpression newParam, ParameterExpression oldParam) : this(new[] { newParam }, new[] { oldParam }) { }
public NewExpressionVisitor(ParameterExpression[] newParams, ParameterExpression[] oldParams)
{
this._newParameters = newParams;
this._oldParameters = oldParams;
}
public Expression Replace(Expression exp) => this.Visit(exp); protected override Expression VisitParameter(ParameterExpression node)
{
for (var a = 0; a < _oldParameters.Length; a++)
if (_oldParameters[a] == node)
return _newParameters[a];
return node;
}
}
#endregion
}
}

以上代码是将表达式拼接扩展至6个泛型参数,以此类推。

因为属于同一个命名空间,可以直接使用。

FreeSql之Expression表达式拼接参数扩展的更多相关文章

  1. 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)

    一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...

  2. Expression表达式目录树动态拼接 反射获取泛型方法

    class TestOne { public String[] arr = { "1", "2", "3" }; public class ...

  3. 委托、匿名委托、Lambda 表达式、Expression表达式树之刨根问底

    本篇不是对标题所述之概念的入门文章,重点在阐述它们的异同点和应用场景.各位看官,这里就不啰嗦了,直接上代码. 首先定义一个泛型委托类型,如下: public delegate T Function&l ...

  4. .net 系列:Expression表达式树、lambda、匿名委托 的使用

    首先定义一个泛型委托类型,如下: public delegate T Function<T>(T a, T b); 实现泛型委托的主体代码,并调用: public static strin ...

  5. .net 系列:Expression表达式树、lambda、匿名委托 的使用【转】

    https://www.cnblogs.com/nicholashjh/p/7928205.html 首先定义一个泛型委托类型,如下: public delegate T Function<T& ...

  6. ASP.NET MVC:Expression Trees 作为参数简化查询

    ASP.NET MVC 引入了 ModelBinder 技术,让我们可以在 Action 中以强类型参数的形式接收 Request 中的数据,极大的方便了我们的编程,提高了生产力.在查询 Action ...

  7. C# 表达式树Lambda扩展(四)

    一.前言 本来计算这篇文章在后面需要运用的时候写的,但是既然写到表达式的扩展呢,就一起写完吧. 看到这个标题就有一种疑问,Lambda表达式本来就是表达式树,还需要怎么扩展?那就看看下面的内容,你就知 ...

  8. 整理:C#中Expression表达式的妙用

    原文:整理:C#中Expression表达式的妙用 一.目的:通过示例了解C#中Expression表达式的作用,通过表达式和反射可以写出很优雅的代码和架构,也可以完成一些看似不可能完成的任务 二.示 ...

  9. 【转】Linux 技巧: Bash 参数和参数扩展

    重点看下清单7 现在,很多 Linux® 和 UNIX® 系统上都有 bash shell,它是 Linux 上常见的默认 shell.通过本文,您将了解到如何在 bash 脚本中处理参数和选项,以及 ...

随机推荐

  1. k8s 日志收集之 EFK

    如今越来越多的应用部署在容器之中,如何收集日志也是一个很重要的问题.服务出问题了,排查问题需要给开发看日志.服务一般会在多个不同的 pod 中,一个一个的登进去看也的确不方便.业务数据统计也需要日志. ...

  2. dfs求连通块

    递归 递归是什么?绝大部分人都会说:自己调用自己,刚开始我也是这样理解递归的.确实没错,递归的确是自己调用自己.递归简单的应用:编写一个能计算斐波那契数列的函数,也就是这样: int fb(int n ...

  3. python stats画正态分布、指数分布、对数正态分布的QQ图

    stats.probplot(grade, dist=stats.norm, plot=plt) #正态分布 # stats.probplot(grade, dist=stats.expon, plo ...

  4. 1.认识numpy的数组

    认识ndarray --ndarray:用于存储单一数据类型的多维数组 ndarray基础属性的认识 import numpy as np #将numpy简写为np方便调用 1.通过以下实例来认识ar ...

  5. 解析分布式应用框架Ray架构源码

    摘要:Ray的定位是分布式应用框架,主要目标是使能分布式应用的开发和运行. Ray是UC Berkeley大学 RISE lab(前AMP lab) 2017年12月 开源的新一代分布式应用框架(刚发 ...

  6. pip软件包管理工具介绍及基本使用

    pip软件包管理工具介绍及基本使用 一分耕耘,一分收获,要收获得好,必须耕耘得好.-- 徐特立 一.pip软件包管理工具介绍: 定义:pip是Python包管理工具 作用:对Python包的查找.下载 ...

  7. 阿里一面CyclicBarrier和CountDownLatch的区别是啥

    引言 前面一篇文章我们<Java高并发编程基础三大利器之CountDownLatch>它有一个缺点,就是它的计数器只能够使用一次,也就是说当计数器(state)减到为 0的时候,如果 再有 ...

  8. canvas绘制图像轮廓效果

    在2d图形可视化开发中,经常要绘制对象的选中效果. 一般来说,表达对象选中可以使用边框,轮廓或者发光的效果.  发光的效果,可以使用canvas的阴影功能,比较容易实现,此处不在赘述. 绘制边框 绘制 ...

  9. 简易计算器实现:while循环+switch语句

    个人练习: 写一个计算器,要求实现加减乘除功能,并且能循环接收新的数据,通过用户交互实现(即Scanner对象) 用到了 while循环 switch语句,实现了数据的循环输入并计算!!!!妙啊!!! ...

  10. DAOS 分布式异步对象存储|安全模型

    DAOS 使用了一个灵活的安全模型,将身份验证和授权分离开来.它的设计令其对 I/O 的影响被降到最小. DAOS 对用于 I/O 传输的网络结构没有提供任何传输安全性保障.在部署 DAOS 时,管理 ...