How do I add more than two conditions to an Expression dynamically?

Asked

Viewed 1,058 times

2

I need to pass a list of Expressions as a parameter and create the Ands in the most dynamic way possible.

Just like that, whenever I add a new Expression on the list, I’m going to have to change the class that Expression also.

ParameterExpression c = Expression.Parameter(typeof(Boleto), "Boleto");
var temNegociacao = Expression.IsFalse(Expression.Property(c, "Negociacao"));
var status = Expression.IsTrue(Expression.Property(c, "Status"));
var bolsa = Expression.LessThan(Expression.Property(c, "Bolsa"), Expression.Constant(100.0));
var aberto = Expression.IsTrue(Expression.Property(c, "Aberto"));
var periodoLetivo = Expression.IsTrue(Expression.Property(c, "Periodo"));

Expression<Func<Billet, bool>> condition =
Expression.Lambda<Func<Billet, bool>>(
Expression.And(
Expression.And(temNegociacao,
Expression.And(status,
Expression.And(bolsa,
Expression.And(aberto, periodoLetivo)))), c));

return _dbSet.Where(condition).ToList();
  • Explain better what you want. Want to use a And or Or? Not getting it? What’s the problem?

  • I updated the question. I managed to create the condition with an and, but I need to create the condition from a list of Expressions, so that when I build the class that returns the Expressions and add a new Expression, it returns to Expression with all the mounted And

  • 4

    It may be me, but it seems that in your question you do not want to have a goal, but when you reach the goal, you want to double the goal. (The Portuguese will understand nothing :) )

  • kkkkk. That’s right, I’m trying to apply an automated pattern to add the ribbons in Where. Then I will have a list of Expressions, then I need to concatenate with and the conditions, so I add a new, return already know concatenate the conditions.

1 answer

2


Expression trees are valid ways to build a predicate for use with the Entity Framework, but in this case I think you are complicating.

Where returns IQueryable. The object that implements IQueryable not necessarily a materialized list, so you can use Where several times if you like. For example:

return _dbSet.Where(x => !x.Negociacao)
             .Where(x => x.Status)
             .Where(x => x.Bolsa < 100)
             .Where(x => x.Aberto)
             .Where(x => x.Periodo)
             .ToList();

This returns the same thing as your expression, apart from having a more interesting readability.

In fact, try a test like the one below:

var sql = ((ObjectQuery)_dbSet.Where(x => !x.Negociacao)
             .Where(x => x.Status)
             .Where(x => x.Bolsa < 100)
             .Where(x => x.Aberto)
             .Where(x => x.Periodo)).ToTraceString();

sql will have an SQL sentence. Then repeat for your expression mount method. The result should be (almost) the same.

If the goal is to build values according to what has been filled in, you can do so:

var sentenca = _dbSet.Where(x => !x.Negociacao);

if (algumaLogicaVerdadeira)
{
    sentenca = sentenca.Where(x => x.Status);
}

/* Aqui você monta sua regra de negócio. No final, devolva a lista */

return sentenca.ToList();
  • 1

    I took your advice and made a static class returning Iqueryable.

Browser other questions tagged

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