c# - Grouping Lambda Expressions by Operators and Using Them With DapperExtensions' PredicateGroups -


pursuant previous question: pulling apart expression<func<t, object>> - trying make bit more advanced. currently, can this:

var matchingpeople = connection.get<person>(p => p.marketid == marketid); 

which converted dapperextensions fieldpredicate:

// assume i've parsed p => p.marketid == marketid constituent parts: // left = p => p.marketid, theoperator = operator.eq, right = marketid predicates.field(left, theoperator, right); 

i want able this:

var matchingpeople = connection.get<person>(p => p.marketid == marketid && p.firstname == "john" || p.firstname == "jack"); 

and generate sql looks this:

declare @marketid int = 3 declare @firstname01 varchar(max) = 'john' declare @firstname02 varchar(max) = 'jack'  select * person marketid = @marketid , (firstname = @firstname01 or firstname = @firstname02) 

by using dapperextensions compound predicate groups:

// ** code trying dynamically create based on lambda passed in **  var predicategroupand = new predicategroup {operator = groupoperator.and, predicates = new list<ipredicate>()}; // have code determine: left = p => p.marketid, theoperator = operator.eq, right = marketid predicategroupand.predicates.add(predicates.field(left, operator.eq, right));  var predicategroupor = new predicategroup {operator = groupoperator.or, predicates = new list<ipredicate>()}; // have code determine: left = p => p.firstname, theoperator = operator.eq, right = "john" predicategroupand.predicates.add(predicates.field(left, operator.eq, right)); // have code determine: left = p => p.firstname, theoperator = operator.eq, right = "jack" predicategroupor.predicates.add(predicates.field(left, operator.eq, right));  var predicategroupall = new predicategroup // passed dapperextensions' getlist<t> method     {         operator = groupoperator.and, // how set correctly?         predicates = new list<ipredicate> {predicategroupand, predicategroupor}     }; 

my problem seems around way expression trees parsed. assume have lambda expression:

p => p.marketid == marketid && p.firstname == "john" || p.firstname == "jack" 

i can cast binaryexpression. if use binaryexpression.left, get

p.marketid == marketid && p.firstname == "john" 

and binaryexpression.right yields:

p.firstname == "jack" 

also, nodetype of overall binaryexpression seems set last conditional operator of lambda, i.e. expressiontype.orelse

i feel need use recursion , traverse lambda expression right left, haven't been able create compound group predicates want. specifically, how group and lambdas together, , or lambdas together? thanks!

your example lambda,

p => p.marketid == marketid && p.firstname == "john" || p.firstname == "jack" 

is equivilent of

p => (p.marketid == marketid && p.firstname == "john") || p.firstname == "jack" 

because && has higher precendence ||.

because of you'll tree && @ "bottom", (as needs calculated first) || on top:

                         ||                         /  \                        &&  firstname == "jack"                       /  \ p.marketid == marketid    p.firstname == "john" 

once understand operator precedence above makes sense. if want alternative can use brackets force || evaluated first (making end @ bottom of expression tree).

p => p.marketid == marketid && (p.firstname == "john" || p.firstname == "jack") 

your general problem you're approaching wrong. trying create 2 groups, 1 ors , 1 ands. might work in case, not in general one, example, this: (a && b) || (c && d)?

i think should happen each , and each or should translate own predicate group. see "multiple compound predicates (predicate group)" section of linked article. you'd replace binaryexpression predicate group.

in example have (a && b) || c || @ top. want end each time have operator want create predicate group, left , right list of expressions. in logic convert binaryexpression predicate group first use same function convert left , right predicate group

i.e. code sees ||.
creates predicate group ready add expressions list
chooses left first (doesn't matter).
ok, left binary expression, calls predicategroup target library understands
recursion working on && b. chooses left first, sees simple predicate, means can add predicate group, same right
we're original call function has predicate group lower expression on left converted different predicate group , added. goes down right now, simple individual predicate , can add list.

okay, if had crazy like: a && b || c || d && e

ok, taking account higher precedence following: ((a && b) || c) || (d && e) note i'm not 100% sure either bracket put c first && or last, doesn't matter, logic same when visualising tree, start innermost brackets. "leaves" work outwards, using brackets work tree, arriving @ root node, in our case || right of c:

       ||      /    \     ||     &&    /  \   /  \   &&   c d   e  /  \    b 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -