Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the parenthesis in the expression tree

Tags:

c#

lambda

linq

[question] Could you tell me how to create the appropriate expression tree?

[detail] I created following query statically, and result is as expected.

// Datasource
    string[] dataSource = { "John", "Ken", "Mark", "Mary", "Tom" };

// Keyword for Search
    string[] keywords = { "o", "Mark", "Tom" };


    //LINQ Query (Static)
    var query = dataSource.AsQueryable().
    Where(item =>
   (item.ToLower().Contains(keywords[0].ToLower()) ||
   item.ToLower().Contains(keywords[1].ToLower())) &&
   item.ToLower().Contains(keywords[2].ToLower())).
    OrderByDescending(item => item);


//Result
// "Tom"

condition A || condition B && condition C

but I do not know how to code the following condition with expression tree

(condition A || condition B) && condition C

Does anyone tell me how to use the parethesis in the expression tree? So far what I created the body for lambda expression is as follows which does not work well.

public static Expression GetContainsExpression(Expression parameter, string keyword, Expression curBody)
{

    var keywordValue = Expression.Constant(keyword, typeof(string));
      var newBody =
      Expression.Equal( Expression.Call(parameter, ToLower), Expression.Call(keywordValue, ToLower) );

    ///Connect curBody Expression and newBody Expression with "Or" e.s. ||   
    if (curBody != null)
    {
        if (keyword == "Tom")
        {
            return Expression.AndAlso(curBody, newBody);
        }

        else
        return Expression.OrElse(curBody, newBody);
    }
    return newBody;
}
like image 709
shumach5 Avatar asked Sep 18 '25 09:09

shumach5


1 Answers

The parethesis are created automaticaly. You can't avoid it. Expression.OrElse or Expression.AndAlso takes an other expression for left and right and if they are combined expressions as BinaryExpression is they are wrapped in parethesis automatically.

Have a look at this code:

var paramX = Expression.Parameter(typeof(bool), "x");
var paramY = Expression.Parameter(typeof(bool), "y");
var paramZ = Expression.Parameter(typeof(bool), "z");
var expr = Expression.AndAlso(Expression.OrElse(paramX, paramY), paramZ);

If you call expr.ToString() you'll get "((x OrElse y) AndAlso z)". Even the outer AndAlso-Expression is wrapped into parethesis. There is no way to remove them (as I know so far).

A small hint: You can call ToString() on every expression and it will return the created code. Knowing this makes it easier to create dynamic expressions because you've a small ability to see what you get.

like image 96
Sebastian Schumann Avatar answered Sep 20 '25 23:09

Sebastian Schumann