构建动态表达式(初级)

动态创建表达式有啥好处呢?

灵活性强与良好的扩展性是它的最大优点,我们以代码来直观的表示,先简单了解下它的基本语法:

 

 

//委托,封装一个f方法(三个参数,其中最后一个参数是返回值类型)

Func<string, string, int> f = (s1, s2) => (s1 + s2).Length;

Console.WriteLine(f("你好", "hi"));//4

 

 

//表达式目录树using System.Linq.Expressions;

Expression<Func<string, int, bool>> exp = (n, m) => ((n + m).Length > 5);

Console.WriteLine(exp);//(n, m) => ((n + Convert(m)).Length > 5)

Console.WriteLine(exp.Compile());//System.Func`3[System.String,System.Int32,System.Boolean]

Console.WriteLine(exp.Compile()("hi", 123));//False

 

 

再进一步来看个简单的Lambda表达式是怎么创建出来的

//(a, b) => ((a / b) + 5)

ParameterExpression paraLeft = Expression.Parameter(typeof(int), "a");

ParameterExpression paraRight = Expression.Parameter(typeof(int), "b");

BinaryExpression binaryLeft = Expression.Divide(paraLeft, paraRight);

ConstantExpression conRight = Expression.Constant(5, typeof(int));

BinaryExpression binaryBody = Expression.Add(binaryLeft, conRight);

LambdaExpression lambda = Expression.Lambda<Func<int, int, int>>(binaryBody, paraLeft, paraRight);

Func<int, int, int> func = lambda.Compile() as Func<int, int, int>;

Console.WriteLine(func(6, 3));//7

 

 

最后我们来构建一个条件查询语句,做多条件查询的时候,基本的SQL都是写死的,比较繁琐,现在我们来动态构建

//---------------动态创建表达式目录树---------------//

//名字模糊查询tony

//年龄大于等于20

//年龄小于30

string uname = "tony";

List<Expression> expList = new List<Expression>(2);

ParameterExpression parExp = Expression.Parameter(typeof(UserInfo), "infos");//创建需要查找的参数

 

//查姓名infos.UserName.Contains("tony")

MemberExpression unameExp = Expression.Property(parExp, "UserName");

MethodInfo containsMethod = typeof(string).GetMethod("Contains");//using System.Reflection;指定实现Contains方法

ConstantExpression unamevalueExp = Expression.Constant(uname, typeof(string));

MethodCallExpression containsExp = Expression.Call(unameExp, containsMethod, unamevalueExp);

expList.Add(containsExp);

 

//查年龄infos.Age>=20

MemberExpression age1 = Expression.Property(parExp, "Age");

ConstantExpression agevalue1 = Expression.Constant(20, typeof(int));

BinaryExpression gteExp = Expression.GreaterThanOrEqual(age1, agevalue1);

expList.Add(gteExp);

//查年龄infos.Age<30

//if (1 > 2)

//{

MemberExpression age2 = Expression.Property(parExp, "Age");

ConstantExpression agevalue2 = Expression.Constant(30, typeof(int));

BinaryExpression ltExp = Expression.LessThan(age2, agevalue2);

expList.Add(ltExp);

//}

 

 

//把上面的表达式连接起来

Expression whereExp = null;

foreach (var item in expList)

    {

        if (whereExp == null)

                {

                    whereExp = item;

                }

                else

                {

                    whereExp = Expression.And(whereExp, item);

                }

            }

//生成Lambda表达式

//Expression<Func<UserInfo, bool>> lambda = Expression.Lambda<Func<UserInfo, bool>>(whereExp, parExp);

LambdaExpression lambda = Expression.Lambda<Func<UserInfo, bool>>(whereExp, parExp);

Console.WriteLine(lambda);

/*

* 生成结果:

* infos => ((infos.UserName.Contains("tony") And (infos.Age>=20)) And (infos.Age<30))

*/

posted @ 2013-01-24 09:31  kuangkro  阅读(584)  评论(0编辑  收藏  举报