How to evaluate a stand-alone boolean expression in a LINQ expression tree

I am using the standard visitor pattern to iterate through the LINQ expression tree to generate dynamic SQL WHERE clauses.

My problem is, unlike C #, you cannot use a stand-alone boolean expression in SQL; you have to compare it to 1 or 0.

Given this hypothetical lambda expression:

h => h.Enabled || h.Enabled == false

      

It would be easy to mistakenly generate this code:

WHERE Enabled OR Enabled = 0

      

or this code:

WHERE (Enabled = 1) OR (Enabled = 1) = 0

      

Both will generate an SQL error. What logic should I use to get around this without my code starting to look very dumb as I dive into subtrees to figure out what might be?

EDIT: The above example is of course superfluous - I'm only using it to illustrate the point.

Examples that can create this scenario:

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

      

Naturally, the last example is bad style, but my code is designed to work regardless of the skill level of the programmer, so to avoid serving redundant scripts I would be in bad shape on my part.

+2


source to share


2 answers


The following cases are pretty straight forward:

h => h.Enabled == enabled
h => h.Enabled == true

      

These BinaryExpression

are nodes and you can translate them directly to:

WHERE (Enabled = @p0)
WHERE (Enabled = 1)

      

The specific cases you need to handle include:



h => h.Enabled
h => !h.Enabled

      

They are represented differently (as MemberExpression

) in the expression tree . So you need a special case MemberExpression

and determine if it has access to the boolean property or not. If so, then you convert it to canonical form (found UnaryExpression

in the second example):

WHERE (Enabled = 1)
WHERE (Enabled = 0)

      

Alternatively, you can preprocess the expression tree and convert any special cases to their canonical (expression tree form). For example, any MemberExpression

nodes that match the criteria can be converted to correct BinaryExpression

.

+5


source


Is it not possible to completely process the operands before deactivating the operators?

Those. Eval each of:

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

      



to

WHERE (Enabled = 1)

      

and then, in the case where the operators are included in the lambda, process the collection of processed operands with the equivalent SQL to satisfy the requirements of the operator.

0


source







All Articles