Linq2SQL "or / and" operators (ANDed / ORed conditions)
Let's say we need to apply several conditions to select from the "Things" table (unknown account and nature)
if the conditions are known, we can write
db.Things.Where(t=>foo1 && foo2 || foo3);
but if we need to plot this "Where" condition, I can imagine how we can apply the ANDed conditions
IQuerable DesiredThings = db.Things.AsQuerable();
foreach (Condition c in AndedConditions)
DesiredThings = DesiredThings.Where(t => GenerateCondition(c,t));
How about ORed conditions? Note: we do not want to perform unions, unique or any other expensive operations, so it is desirable that the request is generated as if we were writing it ad-hock
Thanks in advance.
Adding
PredicateBuilder: Dynamically Generated Expression Predicates
source to share
You can use Expression class with static methods to do this runtime.
Below is the code for creating a delegate with one argument called a value of type int.It reads from buttom to the top, so the corresponding line is:
var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
the body of the method compares the value of the parameter with the call to the Bar method of the newly created object of type foo
var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
Then a similar expression is created and / or
var orExp = Expression.OrElse(exp1, exp2);
The last thing is the call to compile. This call creates a delegate that can be used in your method call.
hope this helps me not 100% sure about the expression to get the value from the parameter
var exp1 = Expression.Equal(Expression.Parameter(typeof(int),"value"), Expression.Property(Expression.New(typeof(Bar).GetConstructor(new Type[] { })), "Foo"));
var exp2 = Expression.Equal(Expression.Parameter(typeof(int), "value"), Expression.Property(Expression.New(typeof(Foo).GetConstructor(new Type[] { })), "Bar"));
var orExp = Expression.OrElse(exp1, exp2);
var method = LambdaExpression.Lambda(orExp, Expression.Parameter(typeof(int), "value"));
method.Compile();
You may want to call invokation instead of compiling the expression if you need the LambdaExpression to be translated to something other than binary (such as an SQL query)
source to share
For OR
you, you have two options:
- use
Union
/Concat
- write
Expression
in code
The second is closer to .Where(x => {a} || {b})
.
If you are using LINQ-to-SQL you can use Expression.Invoke
to concatenate multiple separate lambda expressions ( see this answer ) - however this is not "t supported in the Entity Framework. In EF, you need to construct the whole expression as one block using Expression.OrElse
; for example here or here .
source to share