昨天琢磨了一整天如何将表达式树转化成条件语句,终究想不通,最终使用ExpressionVisitor,结果是半途而废。

树的解析顺序很难确定,因为无法确定用户输入了什么,当用户输入

 
  
  1. t => t.a > 10 

或者

 
  
  1. t => t.a > 10 && t.b < 2 

那么可以转化Expression为BinaryExpression并处理Left和Right节点以及当前的节点类型,很简单的实现转化。就算处理第二种也是好处理的,因为它的表达式树是可以很容易构造出来的。

 
  
  1.       &&  
  2.   /       \  
  3.   >        < 
  4. /   \    /  \  
  5. t.a 10  t.b  2 

看到这颗树,再结合已知属性很容易就实现转化,这其中如果说困难,也就难在大量的ExpressionType枚举的判断上。可那也只是时间问题。重要的是如果用户输入再复杂的呢。

 
  
  1. // x为局部变量  
  2. t => t.a > ints[0] && t.b < x || t.c != 2 

例如上例我不知道怎么办了。最终放弃这个想法,因为微软已经实现了将Lambda转化为SQL了。但还是不太想放弃,睡觉时无意想到,如果这样做

 
  
  1. Expression<Func<T, bool>> lambda = (t) => t.A > 10 && t.B < 2;  
  2. Console.WriteLine(lambda.ToString());   
  3. // 控制台显示 t => ((t.A > 10) AndAlso (t.B < 2)) 

由此可见在表达式已经自己变成字符串了,之后去查找替换特定的字符串不就可以了。

真是“踏破铁鞋无觅处,得来全不费工夫”。那么剩下的问题就剩下更复杂的解析了,如上一个示例,对变量、数组、集合的访问在树中会被解析为特定的节点,初步想法仍然是在访问器中获取并后期替换,不知道还有么有更好的想法。