解析表达式<func <entity,bool =“”>&gt;到模型?</func <entity,>

时间:2013-12-10 07:46:39

标签: c# parsing expression linq-expressions

我想将Expression<Func<Entity, bool>>解析为模型:

public class Program
{
    static void Main()
    {
        List<Entity> entities = new List<Entity>
        {
            new Entity{ Id = 1, FullName = "Mohammad Dayyan"},
            new Entity{ Id = 2, FullName = "Zahra Ahmadi"},
            new Entity{ Id = 3, FullName = "Milad Ahmadi"},
            new Entity{ Id = 4, FullName = "Ali Dayyan"},
            new Entity{ Id = 5, FullName = "Masoud Ahmadi"},
        };

        //PredicateBuilder is from LinqKit http://www.albahari.com/nutshell/linqkit.aspx
        Expression<Func<Entity, bool>> predicate2 = PredicateBuilder.False<Entity>();
        predicate2 = predicate2.Or(q => q.Id == 1);
        predicate2 = predicate2.Or(q => q.Id == 3);
        predicate2 = predicate2.Or(q => q.Id == 5);

        Expression<Func<Entity, bool>> predicate1 = PredicateBuilder.True<Entity>();
        predicate1 = predicate1.And(q => q.FullName.Contains("Milad"));

//Predicate3 == {((True AndAlso Invoke(q => q.FullName.Contains("Milad"), f)) AndAlso Invoke(f => (((False OrElse (f.Id == 1)) OrElse (f.Id == 3)) OrElse (f.Id == 5)), f))}
        Expression<Func<Entity, bool>> predicate3 = predicate1.And(predicate2);    

        ExpressionModel model = ParseExpression(predicate3);    

        Console.WriteLine(model);
        Console.ReadKey();
    }

    static ExpressionModel ParseExpression(Expression<Func<Entity, bool>> expression)
{

    BinaryExpression binaryExpression = expression.Body as BinaryExpression;
    if (binaryExpression == null) return null;
    Expression left = binaryExpression.Left;
    Expression right = binaryExpression.Right;
    ExpressionModel expressionModel = new ExpressionModel
    {
        NodeType = binaryExpression.NodeType,
        Left = ParseExpression(left),
        Right = ParseExpression(right)
    };
    return expressionModel;
}

static ExpressionModel ParseExpression(Expression expression)
{

    BinaryExpression binaryExpression = expression as BinaryExpression;
    if (binaryExpression == null) return null;
    Expression left = binaryExpression.Left;
    Expression right = binaryExpression.Right;
    ExpressionModel expressionModel = new ExpressionModel
    {
        NodeType = binaryExpression.NodeType,
        Left = ParseExpression(left),
        Right = ParseExpression(right)
    };
    return expressionModel;
}
}


[Serializable]
public class Entity
{
    public int Id { get; set; }
    public string FullName { get; set; }
}

[Serializable]
public class ExpressionModel
{
    public ExpressionModel Left { get; set; }
    public ExpressionModel Right { get; set; }
    public ExpressionType NodeType { get; set; }
}

但是当解析器到达TrueInvoke(q => q.FullName.Contains("Milad"), f) ParseExpression时,方法返回null!

我该如何解决?

1 个答案:

答案 0 :(得分:2)

因为此Invoke(q => q.FullName.Contains("Milad"), f)MethodCallExpression和。{ 这个

BinaryExpression binaryExpression = expression as BinaryExpression;
if (binaryExpression == null) return null;

返回null,因为它不是BinaryExpression。

此外True是一个ConstantExpression。您需要更复杂的代码来解析它并处理所有这些选项。

尝试使用此功能:metalinq