拼接表达式树的原理

 

简单的表达式树,注释写得很清楚

 1             //假如我们要拼接x=>x.Id==1,假如x的类型为User
 2             
 3             //结果是这样:x=>,x是变量名
 4             var parameterExp = Expression.Parameter(typeof(User), "x");
 5             
 6             //结果是这样:x=>x.Id,这句是为了构建访问属性的表达式
 7             //上面这句第一个参数是你要取属性的对象表达式。
 8             //我们要拼的表达式是x=>x.Id==1,==1这块先不管
 9             //其实就是x=>x.Id,那么其实我们就是对x进行取属性值,而x是parameterExp,
10             //第一个参数是parameterExp
11             //第二个参数好说,就是属性名
12             var propertyExp = Expression.Property(parameterExp, "Id");
13             
14             //结果是··没有结果,构建一个常量表达式,值为1(LINQ的世界,一切皆表达式树)
15             //马上就是关键的一步了
16             var constExp = Expression.Constant(1);
17             
18             //结果是:x=>x.Id==1,这个··还需要解释么,很简单,不是么。创建一个相等的表达式,然后传入左边和右边的表达式
19             //当然到这儿还不能用,还需要继续
20             var body = Expression.Equal(propertyExp, constExp);
21             
22             //这句和第二句是我学的时候最难理解的两个地方。这句是将我们的成果封装成能用的
23             //第一个参数就是我们的成果
24             //第二个参数是实现这个成果所需要的参数,那当然是parameterExp,
25             //然后泛型参数Func<User,bool>就是我们想把这个表达式封装成什么样的东西,
26             //此时,lambda的类型就是Expression<Fun<User,bool>>,这个时候就能用了
27             var lambda = Expression.Lambda<Func<User, bool>>(body, parameterExp);
28             

 

下面来个复杂的

 1             //假如我们要拼接x=>x.Name.Contains("aaa"),假如x的类型为TEntity
 2 
 3             //结果是这样:x=>,x是变量名
 4             var parameterExp = Expression.Parameter(typeof(TEntity));
 5 
 6             //结果是这样:x=>x.Name,这句是为了构建访问属性的表达式
 7             //上面这句第一个参数是你要取属性的对象表达式。
 8             //我们要拼的表达式是x =>x.Name.Constant("aaa"),.Constant("aaa")这块先不管,其实就是x=>x.Name,
 9             //那么其实我们就是对x进行取属性值,而x是parameterExp,所以第一个参数是parameterExp,
10             //第二个参数好说,就是属性名
11             var propertyExp = Expression.Property(parameterExp, "Name");
12 
13             //因为我们要拼接的表达式中调用了string类型的Username的Contains方法,所以反射获取string类型的Contains方法
14             var containsMethod = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
15 
16             //结果是··没有结果,构建一个常量表达式,值为1(LINQ的世界,一切皆表达式树)
17             //马上就是关键的一步了
18             var constExp = Expression.Constant("aaa");
19 
20 
21             //结果是:x=>x.Name.Contains("aaa"),
22             //第一个参数,是要调用哪个实例的方法,这里是propertyExp,
23             //第二个是调用哪个方法
24             //第三个是参数
25             var containsExp = Expression.Call(propertyExp, containsMethod, constExp);
26 
27             //这句是将我们的成果封装成能用的,第一个参数就是我们的成果,
28             //第二个参数是实现这个成果所需要的参数,那当然是parameterExp,
29             //然后泛型参数Func<TEntity, bool>就是我们想把这个表达式封装成什么样的东西,
30             //此时,lambda的类型就是Expression<Fun<TEntity, bool>>,这个时候就能用了
31             var lambda = Expression.Lambda<Func<TEntity, bool>>(containsExp, parameterExp);
32             //现在可以直接使用创建的类型
33             tempData = tempData.Where(lambda);

 

多条件动态排序的写法:

 1             bool isAsc = pagination.sord.ToLower() == "asc" ? true : false;
 2             string[] _order = pagination.sidx.Split(',');
 3             MethodCallExpression resultExp = null;
 4             var tempData = DbContext.Set<TEntity>().AsQueryable();
 5 
 6             foreach (string item in _order)
 7             {
 8                 string _orderPart = item;
 9                 _orderPart = Regex.Replace(_orderPart, @"\s+", " ");
10                 string[] _orderArry = _orderPart.Split(' ');
11                 string _orderField = _orderArry[0];
12                 bool sort = isAsc;
13                 if (_orderArry.Length == 2)
14                 {
15                     isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false;
16                 }
17                 var parameter = Expression.Parameter(typeof(TEntity), "t");
18                 var property = typeof(TEntity).GetProperty(_orderField);
19                 var propertyAccess = Expression.MakeMemberAccess(parameter, property);
20                 var orderByExp = Expression.Lambda(propertyAccess, parameter);
21                 resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(TEntity), property.PropertyType }, tempData.Expression, Expression.Quote(orderByExp));
22             }
23 
24 
25 
26             tempData = tempData.Provider.CreateQuery<TEntity>(resultExp);

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值