动态Lambda

注: 有参考文章<https://blog.csdn.net/leewhoee/article/details/8968023>;
      以及文章<http://www.albahari.com/nutshell/predicatebuilder.aspx>

 

此文只为记录,用作之后的借鉴

public static class ExpressionsBuilderExtend
    {
        public static Expression<Func<T, bool>> True<T>() { return x => true; }
        public static Expression<Func<T, bool>> False<T>() { return x => false; }

        /// <summary>
        /// Lambda表达式拼接 Or 语句,此方法适用于Linq to entities,不适用于Linq to sql
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            return left.Compose(right, Expression.Or);
        }

        /// <summary>
        /// Lambda表达式拼接 And 语句,此方法适用于Linq to entities,不适用于Linq to sql
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            return left.Compose(right, Expression.And);
        }

        /// <summary>
        /// Lambda表达式拼接 And 语句,此方法适用于Linq to sql,不适用于Linq to entities
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And4Sql<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            var invokedExpr = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(left.Body, invokedExpr), left.Parameters);
        }

        /// <summary>
        /// Lambda表达式拼接 Or 语句,此方法适用于Linq to sql,不适用于Linq to entities
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or4Sql<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
        {
            var invokedExpr = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.OrElse(left.Body, invokedExpr), left.Parameters);
        }

        /// <summary>
        /// Lambda表达式拼接
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="merge"></param>
        /// <returns></returns>
        public static Expression<T> Compose<T>(this Expression<T> left, Expression<T> right, Func<Expression, Expression, Expression> merge)
        {
            var map = left.Parameters.Select((leftParam, i) => new { leftParam, rightParam = right.Parameters[i] }).ToDictionary(x => x.rightParam, y => y.leftParam);

            var rightBody = ParameterRebinder.ReplaceParameters(map, right.Body);

            return Expression.Lambda<T>(merge(left.Body, rightBody), left.Parameters);
        }
    }

    public class ParameterRebinder : ExpressionVisitor
    {
        private readonly Dictionary<ParameterExpression, ParameterExpression> map;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
        {
            this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
        {
            return new ParameterRebinder(map).Visit(exp);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        protected override Expression VisitParameter(ParameterExpression x)
        {
            ParameterExpression replacement;
            if (map.TryGetValue(x, out replacement))
            {
                x = replacement;
            }
            return base.VisitParameter(x);
        }
    }

 linq to entities 的实际使用Demo

            #region 组织查询条件
            Expression<Func<S_P_Client, bool>> expression = x => x.IsDeleted.Equals("0");
            if (string.IsNullOrEmpty(dto.KeyWord) == false)
            {
                Expression<Func<S_P_Client, bool>> expRight = x => (x.ClientName.Contains(dto.KeyWord) || x.ClientEnglishName.Contains(dto.KeyWord));
                expression = expression.And(expRight);//expression1 = expression1.And();
            }
            if (string.IsNullOrEmpty(dto.CompanyNature) == false)
                expression = expression.And(x => x.CompanyNature.Equals(dto.CompanyNature));
            if (string.IsNullOrEmpty(dto.Status) == false)
                expression = expression.And(x => x.Status.Equals(dto.Status));
            if (string.IsNullOrEmpty(dto.Trade) == false)
                expression = expression.And(x => x.Trade.Equals(dto.Trade));
            #endregion

            using (ProjectEntities entities = new ProjectEntities())
            {
                var all = entities.Set<S_P_Client>().Where(expression).AsQueryable().OrderBy(dto.sort, dto.order.ToLower().Equals("asc")).ToList();
                var rows = all.Skip(dto.offset).Take(dto.limit).ToList();

                return Json(new { total = all.Count(), rows = rows }, JsonRequestBehavior.AllowGet);
            }

 

linq to sql 实际使用Demo

#region 查询内容
            var queryT = from m in contractList.AsQueryable()
                         join tt in tempLst.AsQueryable() on m.ContractID equals tt.ContractID into temp
                         from tg in temp.DefaultIfEmpty()
                         select new ProjectContractListDto
                         {
                                /***省略**/
                         };
            #region 组织lambda表达式
            Expression<Func<ProjectContractListDto, bool>> expression = x => true;
            if (string.IsNullOrEmpty(dto.KeyWord) == false)
            {
                Expression<Func<ProjectContractListDto, bool>> expressionOr = (x => x.ContractID.Contains(dto.KeyWord) || x.ContractName.Contains(dto.KeyWord) || x.SupplierName.Contains(dto.KeyWord));

                expression = expression.And4Sql(expressionOr);
            }

            #endregion

            var list = queryT.Where(expression).AsQueryable().OrderBy(dto.sort, dto.order.ToLower().Equals("asc")).ToList();
            var rows = list.Skip(dto.offset).Take(dto.limit).ToList();
            return Json(new { total = list.Count(), rows = rows }, JsonRequestBehavior.AllowGet);
            #endregion

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值