返回一个条件表达式树的拓展方法

之前做了一个这样的功能,一个页面的查询功能,需要支持很多条件,然后可以点击添加一个条件,类似于Navicat 的这种

代码如下

/// <summary>
        /// 根据条件返回表达式树
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <param name="propName">字段名</param>
        /// <param name="value">值</param>
        /// <param name="ysf">运算符</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> GenerateExpression<T, V>(string propName, V value, string ysf) where T : class, new()
        {
            Type type = typeof(T);
            //获得参数表达式树
            ParameterExpression parameterExpression = Expression.Parameter(type, "item");
            //分割字段
            string[] propNameArray = propName.Split(‘.‘);
            var _propName = propNameArray[0];
            //获取返回类型的公共属性
            int i = 1;
            PropertyInfo propInfo = type.GetProperty(_propName);
            //定义成员表达式树
            MemberExpression memberExpression = Expression.Property(parameterExpression, propInfo);
            //如果字段有导航属性,则执行下面
            for (; i < propNameArray.Length; i++)
            {
                //获取下一级的公共属性
                propInfo = propInfo.PropertyType.GetProperty(propNameArray[i]);
                //获取下一级的成员表达式树
                memberExpression = Expression.Property(memberExpression, propInfo);
            }
            //把参数value转型成和propInfo字段一样的类型
            try
            {
                TypeConverter typeConverter = TypeDescriptor.GetConverter(propInfo.PropertyType);
                var _value = typeConverter.ConvertFrom(value);
                //获取常量表达式树
                ConstantExpression constantExpression = Expression.Constant(_value, propInfo.PropertyType);
                if (ysf == ">")
                {
                    //Expression.GreaterThan表达式树大于比较,成员树memberExpression,常量值树constantExpression,生成二元运算树BinaryExp
                    BinaryExpression BinaryExp = Expression.GreaterThan(memberExpression, constantExpression);
                    return Expression.Lambda<Func<T, bool>>(BinaryExp, new ParameterExpression[] { parameterExpression });
                }
                else if (ysf == ">=")
                {
                    BinaryExpression BinaryExp = Expression.GreaterThanOrEqual(memberExpression, constantExpression);
                    return Expression.Lambda<Func<T, bool>>(BinaryExp, new ParameterExpression[] { parameterExpression });
                }
                else if (ysf == "<")
                {
                    BinaryExpression BinaryExp = Expression.LessThan(memberExpression, constantExpression);
                    return Expression.Lambda<Func<T, bool>>(BinaryExp, new ParameterExpression[] { parameterExpression });
                }
                else if (ysf == "<=")
                {
                    BinaryExpression BinaryExp = Expression.LessThanOrEqual(memberExpression, constantExpression);
                    return Expression.Lambda<Func<T, bool>>(BinaryExp, new ParameterExpression[] { parameterExpression });
                }
                else if (ysf == "=")
                {
                    var methodExpress = Expression.Call(memberExpression, propInfo.PropertyType.GetMethod("Equals", new Type[] { propInfo.PropertyType }), new Expression[] { constantExpression });
                    //返回lamda表达式树
                    return Expression.Lambda<Func<T, bool>>(methodExpress, new ParameterExpression[] { parameterExpression });
                }
                else if (ysf == "like")
                {
                    constantExpression = Expression.Constant(_value, propInfo.PropertyType);
                    var methodExpress = Expression.Call(memberExpression, propInfo.PropertyType.GetMethod("Contains", new Type[] { propInfo.PropertyType }), new Expression[] { constantExpression });
                    //返回lamda表达式树
                    return Expression.Lambda<Func<T, bool>>(methodExpress, new ParameterExpression[] { parameterExpression });
                }
                else
                {
                    new VerifyException("运算符不正确");
                    return null;
                }
            }
            catch (Exception)
            {

                throw new VerifyException($"第{i}个字段的值格式不正确");
            }
        }

原文地址:https://www.cnblogs.com/haixiaocan/p/10699839.html

时间: 2025-01-17 01:25:54

返回一个条件表达式树的拓展方法的相关文章

C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection; using System.Linq.Expressions; namespace INPEXOne.LearnCS { class RefletLambdaDelegate { static object[] para

转载:C#特性-表达式树

原文地址:http://www.cnblogs.com/tianfan/ 表达式树基础 刚接触LINQ的人往往觉得表达式树很不容易理解.通过这篇文章我希望大家看到它其实并不像想象中那么难.您只要有普通的LINQ知识便可以轻松理解本文. 表达式树提供一个将可执行代码转换成数据的方法.如果你要在执行代码之前修改或转换此代码,那么它是非常有价值的.尤其是当你要将C#代码----如LINQ查询表达式转换成其他代码在另一个程序----如SQL数据库里操作它. 但是我在这里颠倒顺序,在文章最后你很容易发现为

C#特性-表达式树

表达式树ExpressionTree 表达式树基础 转载需注明出处:http://www.cnblogs.com/tianfan/ 刚接触LINQ的人往往觉得表达式树很不容易理解.通过这篇文章我希望大家看到它其实并不像想象中那么难.您只要有普通的LINQ知识便可以轻松理解本文. 表达式树提供一个将可执行代码转换成数据的方法.如果你要在执行代码之前修改或转换此代码,那么它是非常有价值的.尤其是当你要将C#代码----如LINQ查询表达式转换成其他代码在另一个程序----如SQL数据库里操作它. 但

Lambda表达式和表达式树

在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在不牺牲可读性的前提下,进一步简化了委托. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑,例如数据筛选,数据排序等等.通常这些操作都是用委托来表示.Lambda表达式是对LINQ数据操作的一种符合语言习惯的表示方式. Lambda表达式不仅可以用来创

C#秘密武器之表达式树

一.表达式树入门 Lambda表达式树很复杂,从概念上很难理解清楚,一句话,表达式树是一种数据结构!这里我们通过下面的这个例子来理解一下表达式树,你就能看个大概: lambda表达式树动态创建方法 static void Main(string[] args) { //i*j+w*x ParameterExpression a = Expression.Parameter(typeof(int),"i"); //创建一个表达式树中的参数,作为一个节点,这里是最下层的节点 Paramet

重构摘要9_简化条件表达式

<重构-改善既有代码的设计>Martin Fowler 摘要: 第九章 简化条件表达式 Decompose Conditinal 分解条件表达式 你有一个复杂的条件(if-then-else)语句 从三个段落中分别提炼出独立函数 Consolidate Conditional Expression 合并条件表达式 你有一系列条件测试,都得到相同结果 将这些测试合并成为一个条件表达式,并将这个条件表达式提炼成为一个独立函数 检查用意更清晰,有时也不用这么做 Consolidate Duplica

C#中的Lambda表达式和表达式树

在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在不牺牲可读性的前提下,进一步简化了委托. LINQ的基本功能就是创建操作管道,以及这些操作需要的任何状态.这些操作表示了各种关于数据的逻辑,例如数据筛选,数据排序等等.通常这些操作都是用委托来表示.Lambda表达式是对LINQ数据操作的一种符合语言习惯的表示方式. Lambda表达式不仅可以用来创

C# Lambda表达式详解,及Lambda表达式树的创建

最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介.优雅. Lambda表达式 "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内联表达式.所有Lambda表达式都使

[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用

[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是时候来引用他解决问题.而本节主要目的就是使用表达式树解决实际问题. 读前必备: 本节学习前,需要掌握以下知识: A.继承 [.net 面向对象编程基础]  (12) 面向对象三大特性——继承 B.多态 [.net 面向对象编程基础]  (13) 面向对象三大特性——多态 C.抽象类 [.net 面向