简单的表达式树,注释写得很清楚
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);