I have a library that converts a lambda expression to an odata filter string using the ExpressionVisitor
class.
For example, the expression o => o.Teste == null && !(o.Date != DateTime.Now)
turns into $filter=Teste eq null and not(Date ne xx/xx/xx)
It works fine. The problem is when I have to group parts of the condition with parentheses (). The parentheses are ignored and it just writes the condition without it.
For example, the expression (o => o.Name != null && o.Name == "Joe") || !(o.Date != DateTime.Now)
turns into $filter=Name ne null and Name eq 'Joe' or not(Date ne xx/xx/xx)
What's weird is that the ExpessionVisitor
doesn't seem to identify the parentheses, it has a NodeType
for not !(expression)
but it doesn't have for (expression)
.
I've been searching for this on Google for two days and I can't seem to find an answer.
Thanks in advance for the Help.
The node type for not isn't for !(expression)
it's just for !expression
- the parentheses aren't part of it.
Parentheses are necessary in source code to indicate the precedence you want. They're not necessary in expression trees because the precedence is inherent in the tree.
If you don't mind sometimes having extra parentheses, you could just make your string conversion always include them. So every time you have an OR or and AND expression with operand expressions x
and y
, just turn that into (x || y)
or (x && y)
, unconditionally including those parentheses. It may not look pretty, but it will always give you the right precedence.
See more on this question at Stackoverflow