How do I extract values from an Expression?

Asked

Viewed 89 times

8

Hello. It is possible to extract from an Expression which filters, arrays, etc were used in a query?

Example:

public class Program
{
    class Produto
    {
        public int Id;
        public string Nome;

        public Produto(int id, string nome)
        {
            this.Id = id;
            this.Nome = nome;
        }
    }

    public static void Main()
    {
        List<Produto> produtos = new List<Produto>();
        produtos.Add(new Produto(1, "Arroz"));
        produtos.Add(new Produto(2, "Feijão"));
        produtos.Add(new Produto(3, "Trigo"));
        produtos.Add(new Produto(4, "Batata"));

        var expression = (from produto in produtos
                          where produto.Id < 3
                          select produto).AsQueryable().Expression;
    }
}

In this case, what I need is to extract from Expression that the filter used was Id < 3

  • This filter used is a business logic. Even if you compare the query restultation with the total domain of the data you will not have to guarantee the filter used, because more than one filter scenario can cause the same result. An example is the equal result between Id > 3 and Nome.EndsWith("a").

1 answer

3


As I told you in the previous question, there are various types of Expressions, which requires you to put additional logic to recover your filter values.

Normally, this parameter Expression is a BinaryExpression. Its components can be obtained as follows::

var expression = meuQueryable.Expression as BinaryExpression;

BinaryExpressions usually possess Left and Right which, in turn, are also Expressions. A code I use to test what kind of expression is Left and Right (not very good, I’m still perfecting) is the following:

            switch (expression.Left.GetType().ToString())
            {
                case "System.Linq.Expressions.LogicalBinaryExpression":
                case "System.Linq.Expressions.MethodBinaryExpression":
                    valorFinalEsquerdo = Condicao(expression.Left);
                    break;
                case "System.Linq.Expressions.UnaryExpression":
                    var body2 = expression.Left as UnaryExpression;

                    if (body2 != null)
                    {
                        var left2 = body2.Operand as MemberExpression;
                        if (left2 != null)
                        {
                            var teste = ReflectionUtils.ExtrairAtributoColumnDeMember(left2.Member);
                            valorFinalEsquerdo = teste.Name;
                        }
                    }
                    break;
                default:
                    var left = expression.Left as MemberExpression;
                    if (left != null)
                    {
                        var teste = ReflectionUtils.ExtrairAtributoColumnDeMember(left.Member);
                        valorFinalEsquerdo = teste.Name;
                    }
                    break;
            }

            switch (expression.Right.GetType().ToString())
            {
                case "System.Linq.Expressions.MethodBinaryExpression":
                    valorFinalDireito = Condicao(expression.Right);
                    break;
                case "System.Linq.Expressions.PropertyExpression":
                        var right2 = expression.Right as MemberExpression;
                        if (right2 != null)
                        {
                            valorFinalDireito = AvaliarExpressao(right2);
                        }

                    break;
                default:
                    var right = expression.Right as ConstantExpression;
                    if (right != null)
                    {
                        valorFinalDireito = right.Value;
                    }
                    break;
            }

The code is part of a function called Condicao, I call recursively. Values are obtained within valorFinalDireito and valorFinalEsquerdo.

  • Thank you. I’m studying this solution.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.