zoukankan      html  css  js  c++  java
  • 拼接表达式树的原理

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

     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);
  • 相关阅读:
    散列
    HDOJ 1005
    ASP.NET会话(Session)模式
    【转】SQLServer 2005新功能,一些性能方面问题,sql 经典语句
    使用委托在用户自定义控件中实现事件响应
    Web.config详解 [转]
    每个分类取最新的几条的SQL实现
    c++中const与函数一起用的时候需要注意什么?
    ASP.NET中定制自己的委托和事件参数类
    asp.net repeat嵌套
  • 原文地址:https://www.cnblogs.com/yanglang/p/9356254.html
Copyright © 2011-2022 走看看