解析入口参数为实体的表达式树

      在学习LINQ的时候碰到了解析表达式树的问题,书上的例子中入口参数为一个单一变量,这个在MSDN中给出了示例代码:

MSDN官方示例:

// Add the following using directive to your code file:
// using System.Linq.Expressions;
// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num <5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation
= (BinaryExpression)exprTree.Body;
ParameterExpression left
= (ParameterExpression)operation.Left;
ConstantExpression right
= (ConstantExpression)operation.Right;
Console.WriteLine(
"Decomposed expression: {0} => {1} {2} {3}",
param.Name, left.Name, operation.NodeType, right.Value);
// This code produces the following output:
// Decomposed expression: num => num LessThan 5

       这里表达式的入口参数是一个int型的变量,表达式左边就是这个参数本身,右边是一个常量,因此用

              ParameterExpression left = (ParameterExpression)operation.Left;

              ConstantExpression right = (ConstantExpression)operation.Right;

来解析即可,但如果入口是一个实体呢,这种情况很常见,应该怎么解析呢,通过向高人请教,最后用编译表达式树终于解决了这个问题:

    //实体类
    public class T
    {
        
public int ID { getset; }
        
public string Name { getset; }
    }

    
//解析表达式树类
    public class Test
    {
        
public void ExpressionTest(Expression<Func<T, bool>> exprTree)
        {
            ParameterExpression param 
= (ParameterExpression)exprTree.Parameters[0];
            BinaryExpression operation 
= (BinaryExpression)exprTree.Body;
            MemberExpression left 
= (MemberExpression)operation.Left;
            MemberExpression right 
= (MemberExpression)operation.Right;

            var result
=Expression.Lambda(right).Compile().DynamicInvoke();
            Console.WriteLine(
"Decomposed expression:{0}=>{1} {2} {3}",
                param.Name,left.Member.Name,operation.NodeType,result.ToString());
        }
    }

    
//调用
    public class Program
    {
        
static void Main(string[] args)
        {
            Test test 
= new Test();
            T t 
= new T() { ID = 1, Name = "abc" };
            test.ExpressionTest(o 
=> o.ID == t.ID);
            test.ExpressionTest(o 
=> o.Name == t.Name);            
            Console.Read();
        }
    }

 运行结果如下:

 

      园子中有位朋友提供了另外一种方法(http://home.cnblogs.com/q/22976/),不过那个方法有一定缺陷,要依赖于实体类型,如果像上面代码中那样把表达式做为一个参数就无能为力了。

原文地址:https://www.cnblogs.com/artwl/p/1985521.html