在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. Python开发环境从零搭建-02-代码编辑器Sublime

    想要从零开始搭建一个Python的开发环境说容易也容易 说难也能难倒一片开发人员,在接下来的一系列视频中,会详细的讲解如何一步步搭建python的开发环境 本文章是搭建环境的第2篇 讲解的内容是:安装 ...

  2. springboot注解之@Configuration 和 @Bean

    1.包结构 2.主程序类 1 /** 2 * 主程序类 3 * @SpringBootApplication:这是一个springboot应用 4 * 5 * @SpringBootApplicati ...

  3. NoSQL安装与操作

    redis操作: redis的启动与关闭:注意:(需要关闭防火墙) redis的启动:redis-server redis.conf redis的登录:redis-cli -a pass redis的 ...

  4. MySQL基础知识:MySQL Connection和Session

    在connection的生命里,会一直有一个user thread(以及user thread对应的THD)陪伴它. Connection和Session概念 来自Stackoverflow的一个回答 ...

  5. MyBatis工程搭建&MyBatis实现Mapper配置查询

    一.MyMyBatis工程搭建 新建Maven项目:mybatis-demo 准备数据源 1 # 删除mybatis_demo数据库 2 drop database if exists mybatis ...

  6. Topshelf一个用于使用.NET构建Windows服务框架

    1 Topshelf是什么? Topshelf是用于托管使用.NET框架编写的Windows服务的框架.服务的创建得到简化,从而使开发人员可以创建一个简单的控制台应用程序,可以使用Topshelf将其 ...

  7. [leetcode] 单调栈

    本文总结单调栈算法. 原问题 学习一个算法,我们需要清楚的是:这个算法最原始的问题背景是什么样的? 下一个更小元素 给定一个数组 nums,返回每个元素的下一个更小的元素的下标 res,即 res[i ...

  8. 计算机体系结构——CH4 输入输出系统

    计算机体系结构--CH4 输入输出系统 右键点击查看图像,查看清晰图像 X-mind 计算机体系结构--CH4 输入输出系统 输入输出原理 特点 实时性 与设备无关性 异步性 输入输出系统的组织方式 ...

  9. VS2019 自定义项目模板

    前言: 使用"宇宙最强IDE"开发项目时,都需要根据不同情况选择一个项目模板,来满足开发需求:如下 VS为我们提供了基础的项目模板,但现有项目模板未包含基础功能如:日志输出.审计日 ...

  10. [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.4 Cuk变换器实例

    2.4 Cuk 变换器 作为第二个示例,考虑图2.20(a)的变换器.该变换器执行类似于降压-升压变换器的直流转换功能:它可以增加或减小直流电压的幅值,并且可以反转极性.使用晶体管和二极管的实际实现如 ...