动态Lambda进阶一

直接上代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ConsoleApplication1
{
    public static class Extensions
    {
        public static Predicate<T> ToPredicate<T>(this Func<T, bool> source)
        {
            Predicate<T> result = new Predicate<T>(source);
            return result;
        }
    }

    public class LambdaExtention<T>
    {
        /// <summary>
        /// 表达式集合
        /// </summary>
        private List<Expression> m_lstExpression = null;

        /// <summary>
        /// 参数
        /// </summary>
        private ParameterExpression m_Parameter = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public LambdaExtention()
        {
            m_lstExpression = new List<Expression>();
            m_Parameter = Expression.Parameter(typeof(T), "x");
        }

        /// <summary>
        /// 字符串Contains筛选
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void Contains(Expression<Func<T, object>> expProperty, object objValue)
        {
            Expression expRes = Expression.Call(GetMemberExpression(expProperty), typeof(string).GetMethod("Contains"),
                                Expression.Constant(objValue));

            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 等于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void Equal(Expression<Func<T, object>> expProperty, object objValue)
        {
            var member = GetMemberExpression(expProperty);
            Expression expRes = Expression.Equal(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 等于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void Equal(string strProperty, object objValue)
        {
            var member = GetMemberExpression(strProperty);
            Expression expRes = Expression.Equal(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 小于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void LessThan(Expression<Func<T, object>> expProperty, object objValue)
        {
            var member = GetMemberExpression(expProperty);
            Expression expRes = Expression.LessThan(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 小于等于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void LessThanOrEqual(Expression<Func<T, object>> expProperty, object objValue)
        {
            var member = GetMemberExpression(expProperty);
            Expression expRes = Expression.LessThanOrEqual(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 大于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void GreaterThan(Expression<Func<T, object>> expProperty, object objValue)
        {
            var member = GetMemberExpression(expProperty);
            Expression expRes = Expression.GreaterThan(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        ///  大于等于
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        public void GreaterThanOrEqual(Expression<Func<T, object>> expProperty, object objValue)
        {
            var member = GetMemberExpression(expProperty);
            Expression expRes = Expression.GreaterThanOrEqual(member, Expression.Constant(objValue, member.Type));
            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 为真方法
        /// </summary>
        /// <param name="expProperty">表达式属性</param>
        /// <param name="objValue">值</param>
        /// <param name="typeName">类名名称</param>
        /// <param name="methodName">方法名称</param>
        public void IsTureMethod(Expression<Func<T, object>> expProperty, object objValue, string typeName, string methodName)
        {
            Expression expRes = Expression.IsTrue(GetMemberExpression(expProperty), Type.GetType(typeName).GetMethod(methodName)
                             );

            m_lstExpression.Add(expRes);
        }

        /// <summary>
        /// 获得Lambda
        /// </summary>
        /// <returns>返回Lambda</returns>
        private LambdaExpression GetLambda()
        {
            Expression whereExpr = null;

            foreach (var expr in this.m_lstExpression)
            {
                if (whereExpr == null)
                {
                    whereExpr = expr;
                }
                else
                {
                    whereExpr = Expression.And(whereExpr, expr);
                }
            }

            if (whereExpr == null)
            {
                return null;
            }

            return Expression.Lambda(whereExpr, m_Parameter);
        }

        /// <summary>
        /// 获得谓词
        /// </summary>
        /// <returns>返回谓词</returns>
        public Predicate<T> GetPredicate()
        {
            Func<T, bool> match = (Func<T, bool>)GetLambda().Compile();

            return match.ToPredicate();
        }

        /// <summary>
        /// 获得方法
        /// </summary>
        /// <returns>返回方法</returns>
        public Func<T, bool> GetFunc()
        {
            Func<T, bool> match = (Func<T, bool>)GetLambda().Compile();

            return match;
        }

        /// <summary>
        /// 获得MemberExpression
        /// </summary>
        /// <param name="exp">表达式属性</param>
        /// <returns>返回MemberExpression</returns>
        private MemberExpression GetMemberExpression(Expression<Func<T, object>> exp)
        {
            var arrSplit = exp.Body.ToString().Split("(.)".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            var strProperty = string.Join(".", arrSplit, 1, arrSplit.Length - 1);
            MemberExpression member = GetMemberExpression(strProperty);
            return member;
        }

        /// <summary>
        /// 获得MemberExpression
        /// </summary>
        /// <param name="strProperty">表达式属性</param>
        /// <returns>返回MemberExpression</returns>
        private MemberExpression GetMemberExpression(string strProperty)
        {
            MemberExpression member;

            if (strProperty.Contains(‘.‘))
            {
                string[] aryProperty = strProperty.Split(‘.‘);

                member = Expression.Property(m_Parameter, aryProperty[0]);

                for (int i = 1; i < aryProperty.Length; i++)
                {
                    member = Expression.Property(member, member.Type, aryProperty[i]);
                }
            }
            else
            {
                member = Expression.Property(m_Parameter, strProperty);
            }

            return member;
        }
    }
}

调用示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> lstStu = new List<Student>();
            lstStu.Add(new Student() { No = "001", Name = "zhangsan", Classes = new Classes() { ClassID = "002" } });
            lstStu.Add(new Student() { No = "002", Name = "lisi", Classes = new Classes() { ClassID = "003" } });
            lstStu.Add(new Student() { No = "003", Name = "wangwu", Classes = new Classes() { ClassID = "004" } });
            lstStu.Add(new Student() { No = "004", Name = "maliu", Classes = new Classes() { ClassID = "005" } });

            var le = new LambdaExtention<Student>();

            ////自定义方法
            le.IsTureMethod(x => x.Classes.ClassID, "0", "ConsoleApplication1.Test", "Show");

            ////两种写法
            le.Equal(x => x.Classes.ClassID, "002");
            le.Equal("Classes.ClassID", "002");

            List<Student> stu = lstStu.FindAll(le.GetPredicate());

            foreach (var item in stu)
            {
                Console.WriteLine(item.No);
            }

            Console.Read();
        }
    }

    static class Test
    {
        public static bool Show(string str)
        {
            return false;
        }
    }
}

文章引用自:http://blog.jobbole.com/99431/

时间: 2024-10-29 08:58:49

动态Lambda进阶一的相关文章

SqlDataReader生成动态Lambda表达式

上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少.主要是首行转换的时候动态生成了委托. 后面的转换都是直接调用委托,省去了多次用反射带来的性能损失. 今天在对SqlServer返回的流对象 SqlDataReader 进行处理,也采用动态生成Lambda表达式的方式转换实体. 先上一版代码 1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using Syst

动态Lambda表达式打印HelloWorld

最近在用C#与数据库打交道.开发过程中采用了ORM模型(以前是纯sql玩法,复杂的逻辑用存储过程做). 为了能通过配置文件动态地查询字段,也就是说需要能这样写: db.AsQuery<T>.Select("字段")//伪代码 通过多方查找终于找到了方案,那就是用动态Lambda表达式树(.net3.5以后的版本支持). 后来看别人写的ORM代码中,将C#代码转为SQL语句时出采用了表达式树,所以马上提起了学习兴趣. 先写着写一个hello world ,就是动态地拼出一个

C# 构建动态Lambda表达式

做CURD开发的过程中,通常都会需要GetList,然而查询条件是一个可能变化的需求,如何从容对应需求变化呢? 首先,我们来设计一个套路,尝试以最小的工作量完成一次查询条件的需求变更 1.UI收集查询数据 2.UI将查询数据传递给Service 3.Service从查询配置(数据库.JSON.XML)中匹配出查询条件,并赋予UI取得的值 4.Service根据查询配置(已赋值)构建查询表达式. 5.执行查询返回数据. 大概流程如下图所示: 下面上代码,希望有人能看懂 >< 查询保存设置 pub

c# ef 排序字段动态,构建动态Lambda和扩展方法OrderBy

1.动态构建排序 Lambda /// <summary> /// 获取排序Lambda(如果动态排序,类型不同会导致转换失败) /// </summary> /// <typeparam name="T">数据字段类型</typeparam> /// <typeparam name="Tkey">排序字段类型</typeparam> /// <param name="defau

Linq之Lambda进阶

目录 写在前面 系列文章 带有标准查询运算符的Lambda Lambda中类型推断 Lambda表达式中变量作用域 异步Lambda 总结 写在前面 上篇文章介绍了Lambda的基本概念以及匿名方法,本篇继续介绍Lambda的一些内容,既然学了,就要总结的全面一点. 系列文章 Linq之Lambda表达式初步认识 带有标准查询运算符的Lambda 什么事标准查询运算符? “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法. 大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实

C# 动态Lambda表达式

借助一个强大的Nuget 包可以很方便地解析执行Lambda表达式格式的字符串:System.Linq.Dynamic.Core github: https://github.com/StefH/System.Linq.Dynamic.Core // 匿名类 //匿名类var a = new { Age = 1, Name = "小姐姐" }; Type aType = a.GetType(); var dataParameter = Expression.Parameter(aTyp

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

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

Linq动态查询简易解决之道(原创)

因为项目需要使用Linq来查询数据,但是在多条件查询时,需要使用一大堆if(...!=string.empty)等判断条件感觉不是很优雅.网上搜索以下,大概找到了两种办法,一种是老外写的一个类,感觉用着麻烦:还有就是提供一扩展个方法,参数为某个类型,当调用该方法时,用反射去遍历这个类型的属性,再拿动态查询参数和属性值去比较,然后构建动态lambda表达式,这个也有缺陷,就是需要遍历类型的所有属性,而且构建lambda表达式只能构建==类型表达式,有局限性.所以自己琢磨了一个办法,调用时只需一行代

Linq之Expression进阶

目录 写在前面 系列文章 表达式树解析 表达式树特性 编译表达树 总结 写在前面 让我们首先简单回顾一下上篇文章介绍的内容,上篇文章介绍了表达式树的基本概念(表达式树又称为“表达式目录树”,以数据形式表示语言级代码,它是一种抽象语法树或者说是一种数据结构),以及两种创建表达式树目录树的方式:以lambda表达式的方式创建,通过API静态方法创建.由于不能将有语句体的lambda表达式转换为表达式树,而有时我们又有这样的需求,那么这种情况你可以选择API的静态方法方式创建,在 .NET Frame