开发者

C#如何动态创建lambda表达式

目录
  • C#动态创建lambda表达式
  • Lambda表达式动态拼接生成工具类
  • 总结

C#动态创建lambda表达式

近日在使用了一下EF框架,在做多条件where查询的时候不知道怎么做,网上找了找,一开始用context.Database.SqlQuery<T>方法写sql语句,之后遇到了SqlParamterCollection已在另一定义的问题,找了一下,大概知道什么问题,觉得用EF真的有点不方便,还不如用Dapper开发效率快,之后又在网上搜了搜关键字EF框架多条件Where查询就打开了新世界的大门。

动态创建lambda表达式,我跟着学习了一下写的

代码如下:

     //querydata 是Dictionary<string,string> 放着要查询的属性名和相应的值
      ParameterExpression pe = Expression.Parameter(typeof(Customer), "customer");//lambda表示式里的参数我这边是单参数
      Expression left;//相当于 a=b 的 a
      Expression right;//相当于a=b 的 b
      Expression e;//作为最后形成的表达式的载体
      //先放一个初始值后面被替换不然循环里不方便用     
      left = Expression.Property(pe, typeof(Customer).GetProperty("name"));//Customer.name
      right = Expression.Constant("巅峰白杨");//Constant方法设置属性对应的值
      e = Expression.Equal(left, right);//Customer.name=="巅峰白杨"
      //循环查询条件字典
      foreach (var item in querydata)
      {
        if (!item.Value.ToString().Trim().Equals(""))
        {
          left = Expression.Property(pe, typeof(SFC_Package).GetProperty(item.Key));
          right = Expression.Constant(item.Value);
          if (index == 0)
          {
            e = Expression.Equal(left, right);
            index++;
          }
          else
          {
            if (e != null)
            {
              Expression tempe;
              tempe = Expression.Equal(left, right);
              e = Expression.And(tempe, e);//加了一个&&连接两个判断
            }
          }
        }
      }
     
      IQueryable<Customer> queryableData = db.Customer.AsQueryable<Customer>();//将IEnumerable类型转成IQueryable     
      //Where方法的lambda表达式
      MethodCallExpression whereCallExpression = Expression.Call(
      typeof(Queryable),
      "Where",
      new Type[] { queryableData.ElementType },
      queryableData.Expression,
      Expression.Lambda<Func<SFC_Package, bool>>(e, new ParameterExpression[] { pe }));
      //OrderBy方法的lambda表达式 这边写的有点冗余第一次写不太习惯,想想重复了很多
      var propertyinfo=typeof(Customer).GetProperty("Name");
      Expression body=Expression.Property(pe,propertyinfo);
      Type nametype=propertyinfo.PropertyType;
      MethodCallExpression orderByCallExpression = Expression.Call(
      typeof(Queryable),
      "OrderBy",
      new Type[] { queryableData.ElementType, nametype},//其实可以写成queryableData.Ele开发者_C开发mentType.GetProperty("Name").PropertyType      
      whereCallExpression,
      Expression.Lambda(body, pe));
      //使用已创建好的lambda表达式查询数据 ps:IQueryable和IEnumerable可以转换方便处理查询结果
      IQueryable<SFC_Package> results = queryableData.Provider.CreateQuery<Customer>(orderByCallExpression);

网上还看到一种简单的多条件查询的方法,相当于

var data=db.Customer.Where(o=>o.name=="西门吹雪");
data=data.Where(o=>o.sex="男神")

用循环来多次Where实现多条件查询,感觉可能会造成多次数据库查询,不过用在Linq to Object

上应该挺好的。

最后学习的动态创建lambda表达式地址 点击打开链接

Lambda表达式动态拼接生成工具类

    public static class LambdaUtil<T>
    {
        /// <summary>
        /// lambda表达式:t=>true
        /// </summary>
        /// <returns></returns>
        public static Expression<Func<T, bool>> True()
        {
            return t => true;
        }
 
        /// <summary>
        /// lambda表达式:t=>false
        /// </summary>
        /// <returns></returns>
        public static Expression<Func<T, bool>> False()
        {
            return t => false;
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName
        /// 多用于order排序
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <typeparam name="TKey">返回类型</typeparam>
        /// <param name="propName">属性名</param>
        /// <returns></returns>
        private static Expression<Func<T, TKey>> Order<TKey>(string propName)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个属性
            MemberExpression property = Expression.Property(parameter, propName);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, TKey>>(property, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName==propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Equal(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个相等比较Expression
            BinaryExpression binary = Expression.Equal(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName!=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotEqual(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
          www.devze.com  // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.NotEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName&lt;propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> LessThan(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.LessThan(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName&lt;=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> LessThanOrEqual(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.LessThanOrEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName>propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> GreaterThan(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrFieldwww.devze.com(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.GreaterThan(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName>=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> GreaterThanOrEqual(string propName, object propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.GreaterThanOrEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>{t.contains(propvaluejavascript1) ||...||t.contains(propvalueN)}
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValues">属性值数组</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> In(string propName, string[] propValues)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // left
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            Expression constant = Expression.Constant(false);
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            foreach (string item in propValues)
            {
                // 创建一个带参数方法Expression
                MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right
                // 连接参数方法
                constant = Expression.Or(methodCall, constant);
            }
 
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(constant, new ParameterExpression[] { parameter });
        }
 
        /// <summary>
        /// lambda表达式:t=>{!(t.contains(propvalue1) ||...||t.contains(propvalueN))}
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValues">属性值数组</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotIn(string propName, string[] propValues)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            Expression constant = Expression.Constant(false);
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            foreach (string item in propValues)
            {
                // 创建一个带参数方法Expression
                MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right
                // 连接参数方法
                constant = Expression.Or(methodCall, constant);
            }
 
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(Expression.Not(constant), new ParameterExpression[] { parameter });
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Contains(string propName, string propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> StartWith(string propName, string propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary&pythongt;
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> EndsWith(string propName, string propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
        }
 
        /// <summary>
        /// lambda表达式:!(t=>t.propName.Contains(propValue))
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotContains(string propName, string propValue)
        {
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(Expression.Not(methodCall), parameter);
        }
 
        /// <summary>
        /// lambda表达式:t=>{left and right}
        /// 多用于where条件
        /// </summary>
        /// <param name="left">左侧条件</param>
        /// <param name="right">右侧条件</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            // 创建参数表达式
            InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            // 创建and运算
            BinaryExpression binary = Expression.And(left.Body, invocation);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, left.Parameters);
        }
 
        /// <summary>
        /// lambda表达式:t=>{left or right}
        /// 多用于where条件
        /// </summary>
        /// <param name="left">左侧条件</param>
      编程客栈  /// <param name="right">右侧条件</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            // 创建参数表达式
            InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            // 创建or运算
            BinaryExpression binary = Expression.Or(left.Body, invocation);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, left.Parameters);
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜